1 | /* $Id: ClpConstraintLinear.cpp 1665 2011-01-04 17:55:54Z lou $ */ |
2 | // Copyright (C) 2007, 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 | #include "CoinPragma.hpp" |
7 | #include "CoinHelperFunctions.hpp" |
8 | #include "CoinIndexedVector.hpp" |
9 | #include "ClpSimplex.hpp" |
10 | #include "ClpConstraintLinear.hpp" |
11 | #include "CoinSort.hpp" |
12 | //############################################################################# |
13 | // Constructors / Destructor / Assignment |
14 | //############################################################################# |
15 | |
16 | //------------------------------------------------------------------- |
17 | // Default Constructor |
18 | //------------------------------------------------------------------- |
19 | ClpConstraintLinear::ClpConstraintLinear () |
20 | : ClpConstraint() |
21 | { |
22 | type_ = 0; |
23 | column_ = NULL; |
24 | coefficient_ = NULL; |
25 | numberColumns_ = 0; |
26 | numberCoefficients_ = 0; |
27 | } |
28 | |
29 | //------------------------------------------------------------------- |
30 | // Useful Constructor |
31 | //------------------------------------------------------------------- |
32 | ClpConstraintLinear::ClpConstraintLinear (int row, int numberCoefficents , |
33 | int numberColumns, |
34 | const int * column, const double * coefficient) |
35 | : ClpConstraint() |
36 | { |
37 | type_ = 0; |
38 | rowNumber_ = row; |
39 | numberColumns_ = numberColumns; |
40 | numberCoefficients_ = numberCoefficents; |
41 | column_ = CoinCopyOfArray(column, numberCoefficients_); |
42 | coefficient_ = CoinCopyOfArray(coefficient, numberCoefficients_); |
43 | CoinSort_2(column_, column_ + numberCoefficients_, coefficient_); |
44 | } |
45 | |
46 | //------------------------------------------------------------------- |
47 | // Copy constructor |
48 | //------------------------------------------------------------------- |
49 | ClpConstraintLinear::ClpConstraintLinear (const ClpConstraintLinear & rhs) |
50 | : ClpConstraint(rhs) |
51 | { |
52 | numberColumns_ = rhs.numberColumns_; |
53 | numberCoefficients_ = rhs.numberCoefficients_; |
54 | column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_); |
55 | coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_); |
56 | } |
57 | |
58 | |
59 | //------------------------------------------------------------------- |
60 | // Destructor |
61 | //------------------------------------------------------------------- |
62 | ClpConstraintLinear::~ClpConstraintLinear () |
63 | { |
64 | delete [] column_; |
65 | delete [] coefficient_; |
66 | } |
67 | |
68 | //---------------------------------------------------------------- |
69 | // Assignment operator |
70 | //------------------------------------------------------------------- |
71 | ClpConstraintLinear & |
72 | ClpConstraintLinear::operator=(const ClpConstraintLinear& rhs) |
73 | { |
74 | if (this != &rhs) { |
75 | delete [] column_; |
76 | delete [] coefficient_; |
77 | numberColumns_ = rhs.numberColumns_; |
78 | numberCoefficients_ = rhs.numberCoefficients_; |
79 | column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_); |
80 | coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_); |
81 | } |
82 | return *this; |
83 | } |
84 | //------------------------------------------------------------------- |
85 | // Clone |
86 | //------------------------------------------------------------------- |
87 | ClpConstraint * ClpConstraintLinear::clone() const |
88 | { |
89 | return new ClpConstraintLinear(*this); |
90 | } |
91 | |
92 | // Returns gradient |
93 | int |
94 | ClpConstraintLinear::gradient(const ClpSimplex * model, |
95 | const double * solution, |
96 | double * gradient, |
97 | double & functionValue, |
98 | double & offset, |
99 | bool useScaling, |
100 | bool refresh) const |
101 | { |
102 | if (refresh || !lastGradient_) { |
103 | functionValue_ = 0.0; |
104 | if (!lastGradient_) |
105 | lastGradient_ = new double[numberColumns_]; |
106 | CoinZeroN(lastGradient_, numberColumns_); |
107 | bool scaling = (model && model->rowScale() && useScaling); |
108 | if (!scaling) { |
109 | for (int i = 0; i < numberCoefficients_; i++) { |
110 | int iColumn = column_[i]; |
111 | double value = solution[iColumn]; |
112 | double coefficient = coefficient_[i]; |
113 | functionValue_ += value * coefficient; |
114 | lastGradient_[iColumn] = coefficient; |
115 | } |
116 | } else { |
117 | // do scaling |
118 | const double * columnScale = model->columnScale(); |
119 | for (int i = 0; i < numberCoefficients_; i++) { |
120 | int iColumn = column_[i]; |
121 | double value = solution[iColumn]; // already scaled |
122 | double coefficient = coefficient_[i] * columnScale[iColumn]; |
123 | functionValue_ += value * coefficient; |
124 | lastGradient_[iColumn] = coefficient; |
125 | } |
126 | } |
127 | } |
128 | functionValue = functionValue_; |
129 | offset = 0.0; |
130 | CoinMemcpyN(lastGradient_, numberColumns_, gradient); |
131 | return 0; |
132 | } |
133 | // Resize constraint |
134 | void |
135 | ClpConstraintLinear::resize(int newNumberColumns) |
136 | { |
137 | if (numberColumns_ != newNumberColumns) { |
138 | #ifndef NDEBUG |
139 | int lastColumn = column_[numberCoefficients_-1]; |
140 | #endif |
141 | assert (newNumberColumns > lastColumn); |
142 | delete [] lastGradient_; |
143 | lastGradient_ = NULL; |
144 | numberColumns_ = newNumberColumns; |
145 | } |
146 | } |
147 | // Delete columns in constraint |
148 | void |
149 | ClpConstraintLinear::deleteSome(int numberToDelete, const int * which) |
150 | { |
151 | if (numberToDelete) { |
152 | int i ; |
153 | char * deleted = new char[numberColumns_]; |
154 | memset(deleted, 0, numberColumns_ * sizeof(char)); |
155 | for (i = 0; i < numberToDelete; i++) { |
156 | int j = which[i]; |
157 | if (j >= 0 && j < numberColumns_ && !deleted[j]) { |
158 | deleted[j] = 1; |
159 | } |
160 | } |
161 | int n = 0; |
162 | for (i = 0; i < numberCoefficients_; i++) { |
163 | int iColumn = column_[i]; |
164 | if (!deleted[iColumn]) { |
165 | column_[n] = iColumn; |
166 | coefficient_[n++] = coefficient_[i]; |
167 | } |
168 | } |
169 | numberCoefficients_ = n; |
170 | } |
171 | } |
172 | // Scale constraint |
173 | void |
174 | ClpConstraintLinear::reallyScale(const double * columnScale) |
175 | { |
176 | for (int i = 0; i < numberCoefficients_; i++) { |
177 | int iColumn = column_[i]; |
178 | coefficient_[i] *= columnScale[iColumn]; |
179 | } |
180 | } |
181 | /* Given a zeroed array sets nonlinear columns to 1. |
182 | Returns number of nonlinear columns |
183 | */ |
184 | int |
185 | ClpConstraintLinear::markNonlinear(char *) const |
186 | { |
187 | return 0; |
188 | } |
189 | /* Given a zeroed array sets possible nonzero coefficients to 1. |
190 | Returns number of nonzeros |
191 | */ |
192 | int |
193 | ClpConstraintLinear::markNonzero(char * which) const |
194 | { |
195 | for (int i = 0; i < numberCoefficients_; i++) { |
196 | int iColumn = column_[i]; |
197 | which[iColumn] = 1; |
198 | } |
199 | return numberCoefficients_; |
200 | } |
201 | // Number of coefficients |
202 | int |
203 | ClpConstraintLinear::numberCoefficients() const |
204 | { |
205 | return numberCoefficients_; |
206 | } |
207 | |