source: trunk/Clp/src/ClpLinearObjective.cpp @ 754

Last change on this file since 754 was 754, checked in by andreasw, 14 years ago

first version

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 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//-------------------------------------------------------------------
202// Clone
203//-------------------------------------------------------------------
204ClpObjective * ClpLinearObjective::clone() const
205{
206  return new ClpLinearObjective(*this);
207}
208/* Subset clone.  Duplicates are allowed
209   and order is as given.
210*/
211ClpObjective * 
212ClpLinearObjective::subsetClone (int numberColumns, 
213                           const int * whichColumns) const
214{
215  return new ClpLinearObjective(*this, numberColumns, whichColumns);
216}
217// Resize objective
218void 
219ClpLinearObjective::resize(int newNumberColumns)
220{
221  if (numberColumns_!=newNumberColumns) {
222    int i;
223    double * newArray = new double[newNumberColumns];
224    if (objective_)
225      CoinMemcpyN(objective_,CoinMin(newNumberColumns,numberColumns_),newArray);
226    delete [] objective_;
227    objective_ = newArray;
228    for (i=numberColumns_;i<newNumberColumns;i++) 
229      objective_[i]=0.0;
230    numberColumns_ = newNumberColumns;
231  } 
232 
233}
234// Delete columns in  objective
235void 
236ClpLinearObjective::deleteSome(int numberToDelete, const int * which) 
237{
238  if (objective_) {
239    int i ;
240    char * deleted = new char[numberColumns_];
241    int numberDeleted=0;
242    CoinZeroN(deleted,numberColumns_);
243    for (i=0;i<numberToDelete;i++) {
244      int j = which[i];
245      if (j>=0&&j<numberColumns_&&!deleted[j]) {
246        numberDeleted++;
247        deleted[j]=1;
248      }
249    }
250    int newNumberColumns = numberColumns_-numberDeleted;
251    double * newArray = new double[newNumberColumns];
252    int put=0;
253    for (i=0;i<numberColumns_;i++) {
254      if (!deleted[i]) {
255        newArray[put++]=objective_[i];
256      }
257    }
258    delete [] objective_;
259    objective_ = newArray;
260    delete [] deleted;
261    numberColumns_ = newNumberColumns;
262  }
263}
264// Scale objective
265void 
266ClpLinearObjective::reallyScale(const double * columnScale) 
267{
268  for (int iColumn=0;iColumn<numberColumns_;iColumn++) {
269    objective_[iColumn] *= columnScale[iColumn];
270  }
271}
272
Note: See TracBrowser for help on using the repository browser.