source: trunk/Clp/src/ClpDynamicMatrix.hpp @ 2470

Last change on this file since 2470 was 2385, checked in by unxusr, 9 months ago

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.6 KB
Line 
1/* $Id: ClpDynamicMatrix.hpp 2385 2019-01-06 19:43:06Z stefan $ */
2// Copyright (C) 2004, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef ClpDynamicMatrix_H
7#define ClpDynamicMatrix_H
8
9#include "CoinPragma.hpp"
10
11#include "ClpPackedMatrix.hpp"
12class ClpSimplex;
13/** This implements  a dynamic matrix when we have a limit on the number of
14    "interesting rows". This version inherits from ClpPackedMatrix and knows that
15    the real matrix is gub.  A later version could use shortest path to generate columns.
16
17*/
18
19class ClpDynamicMatrix : public ClpPackedMatrix {
20
21public:
22  /// enums for status of various sorts
23  enum DynamicStatus {
24    soloKey = 0x00,
25    inSmall = 0x01,
26    atUpperBound = 0x02,
27    atLowerBound = 0x03
28  };
29  /**@name Main functions provided */
30  //@{
31  /// Partial pricing
32  virtual void partialPricing(ClpSimplex *model, double start, double end,
33    int &bestSequence, int &numberWanted);
34
35  /**
36        update information for a pivot (and effective rhs)
37     */
38  virtual int updatePivot(ClpSimplex *model, double oldInValue, double oldOutValue);
39  /** Returns effective RHS offset if it is being used.  This is used for long problems
40         or big dynamic or anywhere where going through full columns is
41         expensive.  This may re-compute */
42  virtual double *rhsOffset(ClpSimplex *model, bool forceRefresh = false,
43    bool check = false);
44
45  using ClpPackedMatrix::times;
46  /** Return <code>y + A * scalar *x</code> in <code>y</code>.
47         @pre <code>x</code> must be of size <code>numColumns()</code>
48         @pre <code>y</code> must be of size <code>numRows()</code> */
49  virtual void times(double scalar,
50    const double *x, double *y) const;
51  /// Modifies rhs offset
52  void modifyOffset(int sequence, double amount);
53  /// Gets key value when none in small
54  double keyValue(int iSet) const;
55  /**
56         mode=0  - Set up before "updateTranspose" and "transposeTimes" for duals using extended
57                   updates array (and may use other if dual values pass)
58         mode=1  - Update dual solution after "transposeTimes" using extended rows.
59         mode=2  - Compute all djs and compute key dual infeasibilities
60         mode=3  - Report on key dual infeasibilities
61         mode=4  - Modify before updateTranspose in partial pricing
62     */
63  virtual void dualExpanded(ClpSimplex *model, CoinIndexedVector *array,
64    double *other, int mode);
65  /**
66         mode=0  - Create list of non-key basics in pivotVariable_ using
67                   number as numberBasic in and out
68         mode=1  - Set all key variables as basic
69         mode=2  - return number extra rows needed, number gives maximum number basic
70         mode=3  - before replaceColumn
71         mode=4  - return 1 if can do primal, 2 if dual, 3 if both
72         mode=5  - save any status stuff (when in good state)
73         mode=6  - restore status stuff
74         mode=7  - flag given variable (normally sequenceIn)
75         mode=8  - unflag all variables
76         mode=9  - synchronize costs
77         mode=10  - return 1 if there may be changing bounds on variable (column generation)
78         mode=11  - make sure set is clean (used when a variable rejected - but not flagged)
79         mode=12  - after factorize but before permute stuff
80         mode=13  - at end of simplex to delete stuff
81     */
82  virtual int generalExpanded(ClpSimplex *model, int mode, int &number);
83  /** Purely for column generation and similar ideas.  Allows
84         matrix and any bounds or costs to be updated (sensibly).
85         Returns non-zero if any changes.
86     */
87  virtual int refresh(ClpSimplex *model);
88  /** Creates a variable.  This is called after partial pricing and will modify matrix.
89         Will update bestSequence.
90     */
91  virtual void createVariable(ClpSimplex *model, int &bestSequence);
92  /// Returns reduced cost of a variable
93  virtual double reducedCost(ClpSimplex *model, int sequence) const;
94  /// Does gub crash
95  void gubCrash();
96  /// Writes out model (without names)
97  void writeMps(const char *name);
98  /// Populates initial matrix from dynamic status
99  void initialProblem();
100  /** Adds in a column to gub structure (called from descendant) and returns sequence */
101  int addColumn(CoinBigIndex numberEntries, const int *row, const double *element,
102    double cost, double lower, double upper, int iSet,
103    DynamicStatus status);
104  /** If addColumn forces compression then this allows descendant to know what to do.
105         If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero.
106         Entries at upper bound (really nonzero) never go out (at present).
107     */
108  virtual void packDown(const int *, int) {}
109  /// Gets lower bound (to simplify coding)
110  inline double columnLower(int sequence) const
111  {
112    if (columnLower_)
113      return columnLower_[sequence];
114    else
115      return 0.0;
116  }
117  /// Gets upper bound (to simplify coding)
118  inline double columnUpper(int sequence) const
119  {
120    if (columnUpper_)
121      return columnUpper_[sequence];
122    else
123      return COIN_DBL_MAX;
124  }
125
126  //@}
127
128  /**@name Constructors, destructor */
129  //@{
130  /** Default constructor. */
131  ClpDynamicMatrix();
132  /** This is the real constructor.
133         It assumes factorization frequency will not be changed.
134         This resizes model !!!!
135         The contents of original matrix in model will be taken over and original matrix
136         will be sanitized so can be deleted (to avoid a very small memory leak)
137      */
138  ClpDynamicMatrix(ClpSimplex *model, int numberSets,
139    int numberColumns, const int *starts,
140    const double *lower, const double *upper,
141    const CoinBigIndex *startColumn, const int *row,
142    const double *element, const double *cost,
143    const double *columnLower = NULL, const double *columnUpper = NULL,
144    const unsigned char *status = NULL,
145    const unsigned char *dynamicStatus = NULL);
146
147  /** Destructor */
148  virtual ~ClpDynamicMatrix();
149  //@}
150
151  /**@name Copy method */
152  //@{
153  /** The copy constructor. */
154  ClpDynamicMatrix(const ClpDynamicMatrix &);
155  /** The copy constructor from an CoinPackedMatrix. */
156  ClpDynamicMatrix(const CoinPackedMatrix &);
157
158  ClpDynamicMatrix &operator=(const ClpDynamicMatrix &);
159  /// Clone
160  virtual ClpMatrixBase *clone() const;
161  //@}
162  /**@name gets and sets */
163  //@{
164  /// Status of row slacks
165  inline ClpSimplex::Status getStatus(int sequence) const
166  {
167    return static_cast< ClpSimplex::Status >(status_[sequence] & 7);
168  }
169  inline void setStatus(int sequence, ClpSimplex::Status status)
170  {
171    unsigned char &st_byte = status_[sequence];
172    st_byte = static_cast< unsigned char >(st_byte & ~7);
173    st_byte = static_cast< unsigned char >(st_byte | status);
174  }
175  /// Whether flagged slack
176  inline bool flaggedSlack(int i) const
177  {
178    return (status_[i] & 8) != 0;
179  }
180  inline void setFlaggedSlack(int i)
181  {
182    status_[i] = static_cast< unsigned char >(status_[i] | 8);
183  }
184  inline void unsetFlaggedSlack(int i)
185  {
186    status_[i] = static_cast< unsigned char >(status_[i] & ~8);
187  }
188  /// Number of sets (dynamic rows)
189  inline int numberSets() const
190  {
191    return numberSets_;
192  }
193  /// Number of possible gub variables
194  inline int numberGubEntries() const
195  {
196    return startSet_[numberSets_];
197  }
198  /// Sets
199  inline int *startSets() const
200  {
201    return startSet_;
202  }
203  /// Whether flagged
204  inline bool flagged(int i) const
205  {
206    return (dynamicStatus_[i] & 8) != 0;
207  }
208  inline void setFlagged(int i)
209  {
210    dynamicStatus_[i] = static_cast< unsigned char >(dynamicStatus_[i] | 8);
211  }
212  inline void unsetFlagged(int i)
213  {
214    dynamicStatus_[i] = static_cast< unsigned char >(dynamicStatus_[i] & ~8);
215  }
216  inline void setDynamicStatus(int sequence, DynamicStatus status)
217  {
218    unsigned char &st_byte = dynamicStatus_[sequence];
219    st_byte = static_cast< unsigned char >(st_byte & ~7);
220    st_byte = static_cast< unsigned char >(st_byte | status);
221  }
222  inline DynamicStatus getDynamicStatus(int sequence) const
223  {
224    return static_cast< DynamicStatus >(dynamicStatus_[sequence] & 7);
225  }
226  /// Saved value of objective offset
227  inline double objectiveOffset() const
228  {
229    return objectiveOffset_;
230  }
231  /// Starts of each column
232  inline CoinBigIndex *startColumn() const
233  {
234    return startColumn_;
235  }
236  /// rows
237  inline int *row() const
238  {
239    return row_;
240  }
241  /// elements
242  inline double *element() const
243  {
244    return element_;
245  }
246  /// costs
247  inline double *cost() const
248  {
249    return cost_;
250  }
251  /// ids of active columns (just index here)
252  inline int *id() const
253  {
254    return id_;
255  }
256  /// Optional lower bounds on columns
257  inline double *columnLower() const
258  {
259    return columnLower_;
260  }
261  /// Optional upper bounds on columns
262  inline double *columnUpper() const
263  {
264    return columnUpper_;
265  }
266  /// Lower bounds on sets
267  inline double *lowerSet() const
268  {
269    return lowerSet_;
270  }
271  /// Upper bounds on sets
272  inline double *upperSet() const
273  {
274    return upperSet_;
275  }
276  /// size
277  inline int numberGubColumns() const
278  {
279    return numberGubColumns_;
280  }
281  /// first free
282  inline int firstAvailable() const
283  {
284    return firstAvailable_;
285  }
286  /// first dynamic
287  inline int firstDynamic() const
288  {
289    return firstDynamic_;
290  }
291  /// number of columns in dynamic model
292  inline int lastDynamic() const
293  {
294    return lastDynamic_;
295  }
296  /// number of rows in original model
297  inline int numberStaticRows() const
298  {
299    return numberStaticRows_;
300  }
301  /// size of working matrix (max)
302  inline CoinBigIndex numberElements() const
303  {
304    return numberElements_;
305  }
306  inline int *keyVariable() const
307  {
308    return keyVariable_;
309  }
310  /// Switches off dj checking each factorization (for BIG models)
311  void switchOffCheck();
312  /// Status region for gub slacks
313  inline unsigned char *gubRowStatus() const
314  {
315    return status_;
316  }
317  /// Status region for gub variables
318  inline unsigned char *dynamicStatus() const
319  {
320    return dynamicStatus_;
321  }
322  /// Returns which set a variable is in
323  int whichSet(int sequence) const;
324  //@}
325
326protected:
327  /**@name Data members
328        The data members are protected to allow access for derived classes. */
329  //@{
330  /// Sum of dual infeasibilities
331  double sumDualInfeasibilities_;
332  /// Sum of primal infeasibilities
333  double sumPrimalInfeasibilities_;
334  /// Sum of Dual infeasibilities using tolerance based on error in duals
335  double sumOfRelaxedDualInfeasibilities_;
336  /// Sum of Primal infeasibilities using tolerance based on error in primals
337  double sumOfRelaxedPrimalInfeasibilities_;
338  /// Saved best dual on gub row in pricing
339  double savedBestGubDual_;
340  /// Saved best set in pricing
341  int savedBestSet_;
342  /// Backward pointer to pivot row !!!
343  int *backToPivotRow_;
344  /// Key variable of set (only accurate if none in small problem)
345  mutable int *keyVariable_;
346  /// Backward pointer to extra row
347  int *toIndex_;
348  // Reverse pointer from index to set
349  int *fromIndex_;
350  /// Number of sets (dynamic rows)
351  int numberSets_;
352  /// Number of active sets
353  int numberActiveSets_;
354  /// Saved value of objective offset
355  double objectiveOffset_;
356  /// Lower bounds on sets
357  double *lowerSet_;
358  /// Upper bounds on sets
359  double *upperSet_;
360  /// Status of slack on set
361  unsigned char *status_;
362  /// Pointer back to model
363  ClpSimplex *model_;
364  /// first free
365  int firstAvailable_;
366  /// first free when iteration started
367  int firstAvailableBefore_;
368  /// first dynamic
369  int firstDynamic_;
370  /// number of columns in dynamic model
371  int lastDynamic_;
372  /// number of rows in original model
373  int numberStaticRows_;
374  /// size of working matrix (max)
375  CoinBigIndex numberElements_;
376  /// Number of dual infeasibilities
377  int numberDualInfeasibilities_;
378  /// Number of primal infeasibilities
379  int numberPrimalInfeasibilities_;
380  /** If pricing will declare victory (i.e. no check every factorization).
381         -1 - always check
382         0  - don't check
383         1  - in don't check mode but looks optimal
384     */
385  int noCheck_;
386  /// Infeasibility weight when last full pass done
387  double infeasibilityWeight_;
388  /// size
389  int numberGubColumns_;
390  /// current maximum number of columns (then compress)
391  int maximumGubColumns_;
392  /// current maximum number of elemnts (then compress)
393  CoinBigIndex maximumElements_;
394  /// Start of each set
395  int *startSet_;
396  /// next in chain
397  int *next_;
398  /// Starts of each column
399  CoinBigIndex *startColumn_;
400  /// rows
401  int *row_;
402  /// elements
403  double *element_;
404  /// costs
405  double *cost_;
406  /// ids of active columns (just index here)
407  int *id_;
408  /// for status and which bound
409  unsigned char *dynamicStatus_;
410  /// Optional lower bounds on columns
411  double *columnLower_;
412  /// Optional upper bounds on columns
413  double *columnUpper_;
414  //@}
415};
416
417#endif
418
419/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
420*/
Note: See TracBrowser for help on using the repository browser.