Scippy

SoPlex

Sequential object-oriented simPlex

lpcolsetbase.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-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lpcolsetbase.h
17  * @brief Set of LP columns.
18  */
19 #ifndef _LPCOLSETBASE_H_
20 #define _LPCOLSETBASE_H_
21 
22 #include <assert.h>
23 
24 #include "spxdefines.h"
25 #include "basevectors.h"
26 #include "datakey.h"
27 #include "lpcolbase.h"
28 
29 namespace soplex
30 {
31 /**@brief Set of LP columns.
32  * @ingroup Algebra
33  *
34  * Class LPColSetBase implements a set of \ref LPColBase "LPColBase%s". Unless for memory limitations, any number of LPColBase%s may be
35  * #add%ed to an LPColSetBase. Single or multiple LPColBase%s may be #add%ed to an LPColSetBase, where each method add() comes with
36  * two different signatures. One with and one without a parameter, used for returning the \ref DataKey "DataKeys"
37  * assigned to the new LPColBase%s by the set. See DataKey for a more detailed description of the concept of keys. For the
38  * concept of renumbering LPColBase%s within an LPColSetBase after removal of some LPColBase%s, see DataSet.
39  *
40  * @see DataSet, DataKey
41  */
42 template < class R >
43 class LPColSetBase : protected SVSetBase<R>
44 {
45  template < class S > friend class LPColSetBase;
46 
47 private:
48 
49  // ------------------------------------------------------------------------------------------------------------------
50  /**@name Data */
51  //@{
52 
53  DVectorBase<R> low; ///< vector of lower bounds.
54  DVectorBase<R> up; ///< vector of upper bounds.
55  DVectorBase<R> object; ///< vector of objective coefficients.
56 
57  //@}
58 
59 protected:
60 
61  // ------------------------------------------------------------------------------------------------------------------
62  /**@name Protected helpers */
63  //@{
64 
65  /// Returns the complete SVSetBase.
66  const SVSetBase<R>* colSet() const
67  {
68  return this;
69  }
70 
71  //@}
72 
73 public:
74 
75  // ------------------------------------------------------------------------------------------------------------------
76  /**@name Inquiry */
77  //@{
78 
79  /// Returns the number of LPColBase%s currently in LPColSetBase.
80  int num() const
81  {
82  return SVSetBase<R>::num();
83  }
84 
85  /// Returns maximum number of LPColBase%s currently fitting into LPColSetBase.
86  int max() const
87  {
88  return SVSetBase<R>::max();
89  }
90 
91  ///
92  const VectorBase<R>& maxObj() const
93  {
94  return object;
95  }
96 
97  /// Returns vector of objective values w.r.t. maximization.
99  {
100  return object;
101  }
102 
103  ///
104  const R& maxObj(int i) const
105  {
106  return object[i];
107  }
108 
109  /// Returns objective value (w.r.t. maximization) of \p i 'th LPColBase in LPColSetBase.
110  R& maxObj_w(int i)
111  {
112  return object[i];
113  }
114 
115  ///
116  const R& maxObj(const DataKey& k) const
117  {
118  return object[number(k)];
119  }
120 
121  /// Returns objective value (w.r.t. maximization) of LPColBase with DataKey \p k in LPColSetBase.
122  R& maxObj_w(const DataKey& k)
123  {
124  return object[number(k)];
125  }
126 
127  ///
128  const VectorBase<R>& lower() const
129  {
130  return low;
131  }
132 
133  /// Returns vector of lower bound values.
135  {
136  return low;
137  }
138 
139  ///
140  const R& lower(int i) const
141  {
142  return low[i];
143  }
144 
145  /// Returns lower bound of \p i 'th LPColBase in LPColSetBase.
146  R& lower_w(int i)
147  {
148  return low[i];
149  }
150 
151  ///
152  const R& lower(const DataKey& k) const
153  {
154  return low[number(k)];
155  }
156 
157  /// Returns lower bound of LPColBase with DataKey \p k in LPColSetBase.
158  R& lower_w(const DataKey& k)
159  {
160  return low[number(k)];
161  }
162 
163  ///
164  const VectorBase<R>& upper() const
165  {
166  return up;
167  }
168 
169  /// Returns vector of upper bound values.
171  {
172  return up;
173  }
174 
175  ///
176  const R& upper(int i) const
177  {
178  return up[i];
179  }
180 
181  /// Returns upper bound of \p i 'th LPColBase in LPColSetBase.
182  R& upper_w(int i)
183  {
184  return up[i];
185  }
186 
187  ///
188  const R& upper(const DataKey& k) const
189  {
190  return up[number(k)];
191  }
192 
193  /// Returns upper bound of LPColBase with DataKey \p k in LPColSetBase.
194  R& upper_w(const DataKey& k)
195  {
196  return up[number(k)];
197  }
198 
199  ///
201  {
202  return SVSetBase<R>::operator[](i);
203  }
204 
205  /// Returns colVector of \p i 'th LPColBase in LPColSetBase.
206  const SVectorBase<R>& colVector(int i) const
207  {
208  return SVSetBase<R>::operator[](i);
209  }
210 
211  /// Returns writeable colVector of LPColBase with DataKey \p k in LPColSetBase.
213  {
214  return SVSetBase<R>::operator[](k);
215  }
216 
217  /// Returns colVector of LPColBase with DataKey \p k in LPColSetBase.
218  const SVectorBase<R>& colVector(const DataKey& k) const
219  {
220  return SVSetBase<R>::operator[](k);
221  }
222 
223  /// Returns DataKey of \p i 'th LPColBase in LPColSetBase.
224  DataKey key(int i) const
225  {
226  return SVSetBase<R>::key(i);
227  }
228 
229  /// Returns number of LPColBase with DataKey \p k in LPColSetBase.
230  int number(const DataKey& k) const
231  {
232  return SVSetBase<R>::number(k);
233  }
234 
235  /// Does DataKey \p k belong to LPColSetBase ?
236  bool has(const DataKey& k) const
237  {
238  return SVSetBase<R>::has(k);
239  }
240 
241  //@}
242 
243  // ------------------------------------------------------------------------------------------------------------------
244  /**@name Extension
245  *
246  * All extension methods come with two signatures, one of which providing a parameter to return the assigned
247  * DataKey(s). See DataSet for a more detailed description. All extension methods are designed to automatically
248  * reallocate memory if required.
249  */
250  //@{
251 
252  ///
253  void add(const LPColBase<R>& pcol)
254  {
255  DataKey k;
256  add(k, pcol);
257  }
258 
259  /// Adds p pcol to LPColSetBase.
260  void add(DataKey& pkey, const LPColBase<R>& pcol)
261  {
262  add(pkey, pcol.obj(), pcol.lower(), pcol.colVector(), pcol.upper());
263  }
264 
265  ///
266  void add(const R& pobj, const R& plower, const SVectorBase<R>& pcolVector, const R& pupper)
267  {
268  DataKey k;
269  add(k, pobj, plower, pcolVector, pupper);
270  }
271 
272  /// Adds LPColBase consisting of objective value \p obj, lower bound \p lower, column vector \p colVector and upper bound \p upper to LPColSetBase.
273  void add(DataKey& newkey, const R& obj, const R& newlower, const SVectorBase<R>& newcolVector, const R& newupper)
274  {
275  SVSetBase<R>::add(newkey, newcolVector);
276 
277  if( num() > low.dim() )
278  {
279  low.reDim(num());
280  up.reDim(num());
281  object.reDim(num());
282  }
283 
284  low[num() - 1] = newlower;
285  up[num() - 1] = newupper;
286  object[num() - 1] = obj;
287  }
288 
289  /// Adds LPColBase consisting of left hand side \p lhs, column vector \p colVector, and right hand side \p rhs to LPColSetBase.
290  template < class S >
291  void add(const S* obj, const S* lowerValue, const S* colValues, const int* colIndices, int colSize, const S* upperValue)
292  {
293  DataKey k;
294  add(k, obj, lowerValue, colValues, colIndices, colSize, upperValue);
295  }
296 
297  /// Adds LPColBase consisting of left hand side \p lhs, column vector \p colVector, and right hand side \p rhs to
298  /// LPColSetBase, with DataKey \p key.
299  template < class S >
300  void add(DataKey& newkey, const S* objValue, const S* lowerValue, const S* colValues, const int* colIndices, int colSize, const S* upperValue)
301  {
302  SVSetBase<R>::add(newkey, colValues, colIndices, colSize);
303 
304  if( num() > low.dim() )
305  {
306  low.reDim(num());
307  up.reDim(num());
308  object.reDim(num());
309  }
310 
311  low[num() - 1] = *lowerValue;
312  up[num() - 1] = *upperValue;
313  object[num() - 1] = *objValue;
314  }
315 
316  ///
317  void add(const LPColSetBase<R>& newset)
318  {
319  int i = num();
320 
321  SVSetBase<R>::add(newset);
322 
323  if( num() > low.dim() )
324  {
325  low.reDim(num());
326  up.reDim(num());
327  object.reDim(num());
328  }
329 
330  for( int j = 0; i < num(); ++i, ++j )
331  {
332  low[i] = newset.lower(j);
333  up[i] = newset.upper(j);
334  object[i] = newset.maxObj(j);
335  }
336  }
337 
338  /// Adds all LPColBase%s of \p set to LPColSetBase.
339  void add(DataKey keys[], const LPColSetBase<R>& newset)
340  {
341  int i = num();
342 
343  add(newset);
344 
345  for( int j = 0; i < num(); ++i, ++j )
346  keys[j] = key(i);
347  }
348 
349  /// Extends column \p n to fit \p newmax nonzeros.
350  void xtend(int n, int newmax)
351  {
352  SVSetBase<R>::xtend(colVector_w(n), newmax);
353  }
354 
355  /// Extends column with DataKey \p key to fit \p newmax nonzeros.
356  void xtend(const DataKey& pkey, int pnewmax)
357  {
358  SVSetBase<R>::xtend(colVector_w(pkey), pnewmax);
359  }
360 
361  ///
362  void add2(const DataKey& k, int n, const int idx[], const R val[])
363  {
364  SVSetBase<R>::add2(colVector_w(k), n, idx, val);
365  }
366 
367  /// Adds \p n nonzero (\p idx, \p val)-pairs to \p i 'th colVector.
368  void add2(int i, int n, const int idx[], const R val[])
369  {
370  SVSetBase<R>::add2(colVector_w(i), n, idx, val);
371  }
372 
373  /// Adds \p n nonzero (\p idx, \p val)-pairs to \p i 'th colVector.
374  template < class S >
375  void add2(int i, int n, const int idx[], const S val[])
376  {
377  SVSetBase<R>::add2(colVector_w(i), n, idx, val);
378  }
379 
380  ///
381  SVectorBase<R>& create(int pnonzeros = 0, const R& pobj = 1, const R& plw = 0, const R& pupp = 1)
382  {
383  DataKey k;
384  return create(k, pnonzeros, pobj, plw, pupp);
385  }
386 
387  /// Creates new LPColBase with specified arguments and returns a reference to its column vector.
388  SVectorBase<R>& create(DataKey& newkey, int nonzeros = 0, const R& obj = 1, const R& newlow = 0, const R& newup = 1)
389  {
390  if( num() + 1 > low.dim() )
391  {
392  low.reDim(num() + 1);
393  up.reDim(num() + 1);
394  object.reDim(num() + 1);
395  }
396 
397  low[num()] = newlow;
398  up[num()] = newup;
399  object[num()] = obj;
400 
401  return *SVSetBase<R>::create(newkey, nonzeros);
402  }
403 
404  //@}
405 
406 
407  // ------------------------------------------------------------------------------------------------------------------
408  /**@name Shrinking
409  *
410  * See DataSet for a description of the renumbering of the remaining LPColBase%s in a LPColSetBase after the call of
411  * a removal method.
412  */
413  //@{
414 
415  /// Removes \p i 'th LPColBase.
416  void remove(int i)
417  {
419  low[i] = low[num()];
420  up[i] = up[num()];
421  object[i] = object[num()];
422  low.reDim(num());
423  up.reDim(num());
424  object.reDim(num());
425  }
426 
427  /// Removes LPColBase with DataKey \p k.
428  void remove(const DataKey& k)
429  {
430  remove(number(k));
431  }
432 
433  /// Removes multiple elements.
434  void remove(int perm[])
435  {
436  int j = num();
437 
438  SVSetBase<R>::remove(perm);
439 
440  for( int i = 0; i < j; ++i )
441  {
442  if( perm[i] >= 0 && perm[i] != i )
443  {
444  low[perm[i]] = low[i];
445  up[perm[i]] = up[i];
446  object[perm[i]] = object[i];
447  }
448  }
449 
450  low.reDim(num());
451  up.reDim(num());
452  object.reDim(num());
453  }
454 
455  /// Removes LPColBase%s with numbers \p nums, where \p n is the length of the array \p nums
456  void remove(const int nums[], int n)
457  {
458  DataArray < int > perm(num());
459  remove(nums, n, perm.get_ptr());
460  }
461 
462  /// Removes LPColBase%s with numbers \p nums, where \p n is the length of the array \p nums, and stores the index permutation in array \p perm.
463  void remove(const int nums[], int n, int* perm)
464  {
465  SVSetBase<R>::remove(nums, n, perm);
466 
467  int j = num();
468 
469  for( int i = 0; i < j; ++i )
470  {
471  if( perm[i] >= 0 && perm[i] != i )
472  {
473  low[perm[i]] = low[i];
474  up[perm[i]] = up[i];
475  object[perm[i]] = object[i];
476  }
477  }
478 
479  low.reDim(num());
480  up.reDim(num());
481  object.reDim(num());
482  }
483 
484  /// Removes all LPColBase%s from the set.
485  void clear()
486  {
488  low.reDim(num());
489  up.reDim(num());
490  object.reDim(num());
491  }
492 
493  //@}
494 
495  // ------------------------------------------------------------------------------------------------------------------
496  /**@name Memory Management
497  * See SVSet for a description of the memory management methods.
498  */
499  //@{
500 
501  /// Reallocates memory to be able to store \p newmax LPColBase%s.
502  void reMax(int newmax = 0)
503  {
504  SVSetBase<R>::reMax(newmax);
505  up.reSize(max());
506  low.reSize(max());
507  object.reSize(max());
508  }
509 
510  /// Returns used nonzero memory.
511  int memSize() const
512  {
513  return SVSetBase<R>::memSize();
514  }
515 
516  /// Returns length of nonzero memory.
517  int memMax() const
518  {
519  return SVSetBase<R>::memMax();
520  }
521 
522  /// Resets length of nonzero memory.
523  void memRemax(int newmax)
524  {
525  SVSetBase<R>::memRemax(newmax);
526  }
527 
528  /// Garbage collection in nonzero memory.
529  void memPack()
530  {
532  }
533 
534  //@}
535 
536  // ------------------------------------------------------------------------------------------------------------------
537  /**@name Miscellaneous */
538  //@{
539 
540  /// Checks consistency.
541  bool isConsistent() const
542  {
543 #ifdef ENABLE_CONSISTENCY_CHECKS
544  if( low.dim() != object.dim() )
545  return MSGinconsistent("LPColSetBase");
546  if( low.dim() != up.dim() )
547  return MSGinconsistent("LPColSetBase");
548  if( low.dim() != num() )
549  return MSGinconsistent("LPColSetBase");
550 
551  return low.isConsistent() && up.isConsistent() && SVSetBase<R>::isConsistent();
552 #else
553  return true;
554 #endif
555  }
556 
557  //@}
558 
559  // ------------------------------------------------------------------------------------------------------------------
560  /**@name Constructors / Destructors */
561  //@{
562 
563  /// Default constructor.
564  /** The user can specify the initial maximum number of columns \p max and the initial maximum number of nonzero
565  * entries \p memmax. If these parameters are omitted, a default size is used. However, one can add an arbitrary
566  * number of columns to the LPColSetBase, which may result in automated memory realllocation.
567  */
568  explicit
569  LPColSetBase<R>(int pmax = -1, int pmemmax = -1)
570  : SVSetBase<R>(pmax, pmemmax), low(0), up(0), object(0)
571  {
572  assert(isConsistent());
573  }
574 
575  /// Assignment operator.
577  {
578  if( this != &rs )
579  {
581  low = rs.low;
582  up = rs.up;
583  object = rs.object;
584 
585  assert(isConsistent());
586  }
587 
588  return *this;
589  }
590 
591  /// Assignment operator.
592  template < class S >
594  {
595  if( this != (const LPColSetBase<R>*)(&rs) )
596  {
598  low = rs.low;
599  up = rs.up;
600  object = rs.object;
601 
602  assert(isConsistent());
603  }
604 
605  return *this;
606  }
607 
608  /// Copy constructor.
610  : SVSetBase<R>(rs)
611  , low(rs.low)
612  , up(rs.up)
613  , object(rs.object)
614  {
615  assert(isConsistent());
616  }
617 
618  /// Copy constructor.
619  template < class S >
621  : SVSetBase<R>(rs)
622  , low(rs.low)
623  , up(rs.up)
624  , object(rs.object)
625  {
626  assert(isConsistent());
627  }
628 
629  /// Destructor.
630  virtual ~LPColSetBase<R>()
631  {}
632 
633  //@}
634 };
635 
636 } // namespace soplex
637 #endif // _LPCOLSETBASE_H_