| 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 | |