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