ClpNonLinearCost.hpp
Go to the documentation of this file.
1 /* $Id: ClpNonLinearCost.hpp 1525 2010-02-26 17:27:59Z mjs $ */
2 // Copyright (C) 2002, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 #ifndef ClpNonLinearCost_H
5 #define ClpNonLinearCost_H
6 
7 
8 #include "CoinPragma.hpp"
9 
10 class ClpSimplex;
11 class CoinIndexedVector;
12 
30 /* status has original status and current status
31  0 - below lower so stored is upper
32  1 - in range
33  2 - above upper so stored is lower
34  4 - (for current) - same as original
35 */
36 #define CLP_BELOW_LOWER 0
37 #define CLP_FEASIBLE 1
38 #define CLP_ABOVE_UPPER 2
39 #define CLP_SAME 4
40 inline int originalStatus(unsigned char status)
41 {
42  return (status & 15);
43 }
44 inline int currentStatus(unsigned char status)
45 {
46  return (status >> 4);
47 }
48 inline void setOriginalStatus(unsigned char & status, int value)
49 {
50  status = static_cast<unsigned char>(status & ~15);
51  status = static_cast<unsigned char>(status | value);
52 }
53 inline void setCurrentStatus(unsigned char &status, int value)
54 {
55  status = static_cast<unsigned char>(status & ~(15 << 4));
56  status = static_cast<unsigned char>(status | (value << 4));
57 }
58 inline void setInitialStatus(unsigned char &status)
59 {
60  status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4));
61 }
62 inline void setSameStatus(unsigned char &status)
63 {
64  status = static_cast<unsigned char>(status & ~(15 << 4));
65  status = static_cast<unsigned char>(status | (CLP_SAME << 4));
66 }
67 // Use second version to get more speed
68 //#define FAST_CLPNON
69 #ifndef FAST_CLPNON
70 #define CLP_METHOD1 ((method_&1)!=0)
71 #define CLP_METHOD2 ((method_&2)!=0)
72 #else
73 #define CLP_METHOD1 (false)
74 #define CLP_METHOD2 (true)
75 #endif
77 
78 public:
79 
80 public:
81 
90  ClpNonLinearCost(ClpSimplex * model, int method = 1);
96  ClpNonLinearCost(ClpSimplex * model, const int * starts,
97  const double * lower, const double * cost);
100  // Copy
102  // Assignment
105 
106 
113  void checkInfeasibilities(double oldTolerance = 0.0);
117  void checkInfeasibilities(int numberInArray, const int * index);
124  void checkChanged(int numberInArray, CoinIndexedVector * update);
131  void goThru(int numberInArray, double multiplier,
132  const int * index, const double * work,
133  double * rhs);
136  void goBack(int numberInArray, const int * index,
137  double * rhs);
143  void goBackAll(const CoinIndexedVector * update);
145  void zapCosts();
147  void refreshCosts(const double * columnCosts);
149  void feasibleBounds();
153  double setOne(int sequence, double solutionValue);
156  void setOne(int sequence, double solutionValue, double lowerValue, double upperValue,
157  double costValue = 0.0);
161  int setOneOutgoing(int sequence, double &solutionValue);
163  double nearest(int sequence, double solutionValue);
167  inline double changeInCost(int sequence, double alpha) const {
168  double returnValue = 0.0;
169  if (CLP_METHOD1) {
170  int iRange = whichRange_[sequence] + offset_[sequence];
171  if (alpha > 0.0)
172  returnValue = cost_[iRange] - cost_[iRange-1];
173  else
174  returnValue = cost_[iRange] - cost_[iRange+1];
175  }
176  if (CLP_METHOD2) {
177  returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_;
178  }
179  return returnValue;
180  }
181  inline double changeUpInCost(int sequence) const {
182  double returnValue = 0.0;
183  if (CLP_METHOD1) {
184  int iRange = whichRange_[sequence] + offset_[sequence];
185  if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1))
186  returnValue = cost_[iRange] - cost_[iRange+1];
187  else
188  returnValue = -1.0e100;
189  }
190  if (CLP_METHOD2) {
191  returnValue = -infeasibilityWeight_;
192  }
193  return returnValue;
194  }
195  inline double changeDownInCost(int sequence) const {
196  double returnValue = 0.0;
197  if (CLP_METHOD1) {
198  int iRange = whichRange_[sequence] + offset_[sequence];
199  if (iRange != start_[sequence] && !infeasible(iRange - 1))
200  returnValue = cost_[iRange] - cost_[iRange-1];
201  else
202  returnValue = 1.0e100;
203  }
204  if (CLP_METHOD2) {
205  returnValue = infeasibilityWeight_;
206  }
207  return returnValue;
208  }
210  inline double changeInCost(int sequence, double alpha, double &rhs) {
211  double returnValue = 0.0;
212 #ifdef NONLIN_DEBUG
213  double saveRhs = rhs;
214 #endif
215  if (CLP_METHOD1) {
216  int iRange = whichRange_[sequence] + offset_[sequence];
217  if (alpha > 0.0) {
218  assert(iRange - 1 >= start_[sequence]);
219  offset_[sequence]--;
220  rhs += lower_[iRange] - lower_[iRange-1];
221  returnValue = alpha * (cost_[iRange] - cost_[iRange-1]);
222  } else {
223  assert(iRange + 1 < start_[sequence+1] - 1);
224  offset_[sequence]++;
225  rhs += lower_[iRange+2] - lower_[iRange+1];
226  returnValue = alpha * (cost_[iRange] - cost_[iRange+1]);
227  }
228  }
229  if (CLP_METHOD2) {
230 #ifdef NONLIN_DEBUG
231  double saveRhs1 = rhs;
232  rhs = saveRhs;
233 #endif
234  unsigned char iStatus = status_[sequence];
235  int iWhere = currentStatus(iStatus);
236  if (iWhere == CLP_SAME)
237  iWhere = originalStatus(iStatus);
238  // rhs always increases
239  if (iWhere == CLP_FEASIBLE) {
240  if (alpha > 0.0) {
241  // going below
242  iWhere = CLP_BELOW_LOWER;
243  rhs = COIN_DBL_MAX;
244  } else {
245  // going above
246  iWhere = CLP_ABOVE_UPPER;
247  rhs = COIN_DBL_MAX;
248  }
249  } else if (iWhere == CLP_BELOW_LOWER) {
250  assert (alpha < 0);
251  // going feasible
252  iWhere = CLP_FEASIBLE;
253  rhs += bound_[sequence] - model_->upperRegion()[sequence];
254  } else {
255  assert (iWhere == CLP_ABOVE_UPPER);
256  // going feasible
257  iWhere = CLP_FEASIBLE;
258  rhs += model_->lowerRegion()[sequence] - bound_[sequence];
259  }
260  setCurrentStatus(status_[sequence], iWhere);
261 #ifdef NONLIN_DEBUG
262  assert(saveRhs1 == rhs);
263 #endif
264  returnValue = fabs(alpha) * infeasibilityWeight_;
265  }
266  return returnValue;
267  }
269  inline double lower(int sequence) const {
270  return lower_[whichRange_[sequence] + offset_[sequence]];
271  }
273  inline double upper(int sequence) const {
274  return lower_[whichRange_[sequence] + offset_[sequence] + 1];
275  }
277  inline double cost(int sequence) const {
278  return cost_[whichRange_[sequence] + offset_[sequence]];
279  }
281 
282 
285  inline int numberInfeasibilities() const {
287  return numberInfeasibilities_;
288  }
290  inline double changeInCost() const {
291  return changeCost_;
292  }
294  inline double feasibleCost() const {
295  return feasibleCost_;
296  }
298  double feasibleReportCost() const;
300  inline double sumInfeasibilities() const {
301  return sumInfeasibilities_;
302  }
304  inline double largestInfeasibility() const {
305  return largestInfeasibility_;
306  }
308  inline double averageTheta() const {
309  return averageTheta_;
310  }
311  inline void setAverageTheta(double value) {
312  averageTheta_ = value;
313  }
314  inline void setChangeInCost(double value) {
315  changeCost_ = value;
316  }
317  inline void setMethod(int value) {
318  method_ = value;
319  }
321  inline bool lookBothWays() const {
322  return bothWays_;
323  }
325  inline bool infeasible(int i) const {
327  return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0;
328  }
329  inline void setInfeasible(int i, bool trueFalse) {
330  unsigned int & value = infeasible_[i>>5];
331  int bit = i & 31;
332  if (trueFalse)
333  value |= (1 << bit);
334  else
335  value &= ~(1 << bit);
336  }
337  inline unsigned char * statusArray() const {
338  return status_;
339  }
341  void validate();
343 
344 private:
347  double changeCost_;
364  int * start_;
366  int * whichRange_;
368  int * offset_;
372  double * lower_;
374  double * cost_;
377  // Array to say which regions are infeasible
378  unsigned int * infeasible_;
381  // new stuff
383  unsigned char * status_;
385  double * bound_;
387  double * cost2_;
389  int method_;
391  bool convex_;
393  bool bothWays_;
395 };
396 
397 #endif