source: releases/1.8.0/Clp/src/ClpLinearObjective.cpp @ 2257

Last change on this file since 2257 was 1034, checked in by forrest, 13 years ago

moving branches/devel to trunk

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1// Copyright (C) 2003, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include "CoinPragma.hpp"
5#include "CoinIndexedVector.hpp"
6#include "ClpFactorization.hpp"
7#include "ClpSimplex.hpp"
8#include "ClpLinearObjective.hpp"
9#include "CoinHelperFunctions.hpp"
10
11//#############################################################################
12// Constructors / Destructor / Assignment
13//#############################################################################
14
15//-------------------------------------------------------------------
16// Default Constructor
17//-------------------------------------------------------------------
18ClpLinearObjective::ClpLinearObjective () 
19: ClpObjective()
20{
21  type_=1;
22  objective_=NULL;
23  numberColumns_=0;
24}
25
26//-------------------------------------------------------------------
27// Useful Constructor
28//-------------------------------------------------------------------
29ClpLinearObjective::ClpLinearObjective (const double * objective , 
30                                        int numberColumns) 
31  : ClpObjective()
32{
33  type_=1;
34  numberColumns_=numberColumns;
35  objective_ = CoinCopyOfArray(objective,numberColumns_,0.0);
36}
37
38//-------------------------------------------------------------------
39// Copy constructor
40//-------------------------------------------------------------------
41ClpLinearObjective::ClpLinearObjective (const ClpLinearObjective & rhs) 
42: ClpObjective(rhs)
43{ 
44  numberColumns_=rhs.numberColumns_;
45  objective_ = CoinCopyOfArray(rhs.objective_,numberColumns_);
46}
47/* Subset constructor.  Duplicates are allowed
48   and order is as given.
49*/
50ClpLinearObjective::ClpLinearObjective (const ClpLinearObjective &rhs,
51                                        int numberColumns, 
52                                        const int * whichColumn) 
53: ClpObjective(rhs)
54{
55  objective_=NULL;
56  numberColumns_=0;
57  if (numberColumns>0) {
58    // check valid lists
59    int numberBad=0;
60    int i;
61    for (i=0;i<numberColumns;i++)
62      if (whichColumn[i]<0||whichColumn[i]>=rhs.numberColumns_)
63        numberBad++;
64    if (numberBad)
65      throw CoinError("bad column list", "subset constructor", 
66                      "ClpLinearObjective");
67    numberColumns_ = numberColumns;
68    objective_ = new double[numberColumns_];
69    for (i=0;i<numberColumns_;i++) 
70      objective_[i]=rhs.objective_[whichColumn[i]];
71  }
72}
73 
74
75//-------------------------------------------------------------------
76// Destructor
77//-------------------------------------------------------------------
78ClpLinearObjective::~ClpLinearObjective ()
79{
80  delete [] objective_;
81}
82
83//----------------------------------------------------------------
84// Assignment operator
85//-------------------------------------------------------------------
86ClpLinearObjective &
87ClpLinearObjective::operator=(const ClpLinearObjective& rhs)
88{
89  if (this != &rhs) {
90    ClpObjective::operator=(rhs);
91    numberColumns_=rhs.numberColumns_;
92    delete [] objective_;
93    objective_ = CoinCopyOfArray(rhs.objective_,numberColumns_);
94  }
95  return *this;
96}
97
98// Returns gradient
99double * 
100ClpLinearObjective::gradient(const ClpSimplex * model,
101                             const double * solution, double & offset,bool refresh,
102                             int includeLinear)
103{
104  // not sure what to do about scaling
105  //assert (!model);
106  assert (includeLinear==2); //otherwise need to return all zeros
107  offset=0.0;
108  return objective_;
109}
110 
111/* Returns reduced gradient.Returns an offset (to be added to current one).
112 */
113double 
114ClpLinearObjective::reducedGradient(ClpSimplex * model, double * region,
115                                 bool useFeasibleCosts)
116{
117  int numberRows = model->numberRows();
118  //work space
119  CoinIndexedVector  * workSpace = model->rowArray(0);
120 
121  CoinIndexedVector arrayVector;
122  arrayVector.reserve(numberRows+1);
123 
124  int iRow;
125#ifdef CLP_DEBUG
126  workSpace->checkClear();
127#endif
128  double * array = arrayVector.denseVector();
129  int * index = arrayVector.getIndices();
130  int number=0;
131  const double * cost = model->costRegion();
132  assert (!useFeasibleCosts);
133  const int * pivotVariable = model->pivotVariable();
134  for (iRow=0;iRow<numberRows;iRow++) {
135    int iPivot=pivotVariable[iRow];
136    double value = cost[iPivot];
137    if (value) {
138      array[iRow]=value;
139      index[number++]=iRow;
140    }
141  }
142  arrayVector.setNumElements(number);
143
144  int numberColumns=model->numberColumns();
145 
146  // Btran basic costs
147  double * work = workSpace->denseVector();
148  model->factorization()->updateColumnTranspose(workSpace,&arrayVector);
149  ClpFillN(work,numberRows,0.0);
150  // now look at dual solution
151  double * rowReducedCost = region+numberColumns;
152  double * dual = rowReducedCost;
153  double * rowCost = model->costRegion(0);
154  for (iRow=0;iRow<numberRows;iRow++) {
155    dual[iRow]=array[iRow];
156  }
157  double * dj = region;
158  ClpDisjointCopyN(model->costRegion(1),numberColumns,dj);
159  model->transposeTimes(-1.0,dual,dj);
160  for (iRow=0;iRow<numberRows;iRow++) {
161    // slack
162    double value = dual[iRow];
163    value += rowCost[iRow];
164    rowReducedCost[iRow]=value;
165  }
166  return 0.0;
167}
168/* Returns step length which gives minimum of objective for
169   solution + theta * change vector up to maximum theta.
170   
171   arrays are numberColumns+numberRows
172*/
173double 
174ClpLinearObjective::stepLength(ClpSimplex * model,
175                               const double * solution,
176                               const double * change,
177                               double maximumTheta,
178                               double & currentObj,
179                               double & predictedObj,
180                               double & thetaObj)
181{
182  const double * cost = model->costRegion();
183  double delta=0.0;
184  int numberRows = model->numberRows();
185  int numberColumns = model->numberColumns();
186  currentObj=0.0;
187  thetaObj=0.0;
188  for (int iColumn=0;iColumn<numberColumns+numberRows;iColumn++) {
189    delta += cost[iColumn]*change[iColumn];
190    currentObj += cost[iColumn]*solution[iColumn];
191  }
192  thetaObj =currentObj + delta*maximumTheta;
193  predictedObj =currentObj + delta*maximumTheta;
194  if (delta<0.0) {
195    return maximumTheta;
196  } else {
197    printf("odd linear direction %g\n",delta);
198    return 0.0;
199  }
200}
201// Return objective value (without any ClpModel offset) (model may be NULL)
202double 
203ClpLinearObjective::objectiveValue(const ClpSimplex * model, const double * solution) const
204{
205  const double * cost = objective_;
206  if (model&&model->costRegion())
207    cost = model->costRegion();
208  double currentObj=0.0;
209  for (int iColumn=0;iColumn<numberColumns_;iColumn++) {
210    currentObj += cost[iColumn]*solution[iColumn];
211  }
212  return currentObj;
213}
214//-------------------------------------------------------------------
215// Clone
216//-------------------------------------------------------------------
217ClpObjective * ClpLinearObjective::clone() const
218{
219  return new ClpLinearObjective(*this);
220}
221/* Subset clone.  Duplicates are allowed
222   and order is as given.
223*/
224ClpObjective * 
225ClpLinearObjective::subsetClone (int numberColumns, 
226                           const int * whichColumns) const
227{
228  return new ClpLinearObjective(*this, numberColumns, whichColumns);
229}
230// Resize objective
231void 
232ClpLinearObjective::resize(int newNumberColumns)
233{
234  if (numberColumns_!=newNumberColumns) {
235    int i;
236    double * newArray = new double[newNumberColumns];
237    if (objective_)
238      CoinMemcpyN(objective_,CoinMin(newNumberColumns,numberColumns_),newArray);
239    delete [] objective_;
240    objective_ = newArray;
241    for (i=numberColumns_;i<newNumberColumns;i++) 
242      objective_[i]=0.0;
243    numberColumns_ = newNumberColumns;
244  } 
245 
246}
247// Delete columns in  objective
248void 
249ClpLinearObjective::deleteSome(int numberToDelete, const int * which) 
250{
251  if (objective_) {
252    int i ;
253    char * deleted = new char[numberColumns_];
254    int numberDeleted=0;
255    CoinZeroN(deleted,numberColumns_);
256    for (i=0;i<numberToDelete;i++) {
257      int j = which[i];
258      if (j>=0&&j<numberColumns_&&!deleted[j]) {
259        numberDeleted++;
260        deleted[j]=1;
261      }
262    }
263    int newNumberColumns = numberColumns_-numberDeleted;
264    double * newArray = new double[newNumberColumns];
265    int put=0;
266    for (i=0;i<numberColumns_;i++) {
267      if (!deleted[i]) {
268        newArray[put++]=objective_[i];
269      }
270    }
271    delete [] objective_;
272    objective_ = newArray;
273    delete [] deleted;
274    numberColumns_ = newNumberColumns;
275  }
276}
277// Scale objective
278void 
279ClpLinearObjective::reallyScale(const double * columnScale) 
280{
281  for (int iColumn=0;iColumn<numberColumns_;iColumn++) {
282    objective_[iColumn] *= columnScale[iColumn];
283  }
284}
285
Note: See TracBrowser for help on using the repository browser.