1 | // $Id: CbcFixVariable.cpp 2465 2019-01-03 19:26:52Z unxusr $ |
---|
2 | // Copyright (C) 2002, 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 | // Edwin 11/10/2009-- carved out of CbcBranchActual |
---|
7 | |
---|
8 | #if defined(_MSC_VER) |
---|
9 | // Turn off compiler warning about long names |
---|
10 | #pragma warning(disable : 4786) |
---|
11 | #endif |
---|
12 | #include <cassert> |
---|
13 | #include <cstdlib> |
---|
14 | #include <cmath> |
---|
15 | #include <cfloat> |
---|
16 | //#define CBC_DEBUG |
---|
17 | |
---|
18 | #include "CoinTypes.hpp" |
---|
19 | #include "OsiSolverInterface.hpp" |
---|
20 | #include "OsiSolverBranch.hpp" |
---|
21 | #include "CbcModel.hpp" |
---|
22 | #include "CbcMessage.hpp" |
---|
23 | #include "CbcFixVariable.hpp" |
---|
24 | #include "CbcBranchActual.hpp" |
---|
25 | #include "CoinSort.hpp" |
---|
26 | #include "CoinError.hpp" |
---|
27 | |
---|
28 | //############################################################################## |
---|
29 | |
---|
30 | // Default Constructor |
---|
31 | CbcFixVariable::CbcFixVariable() |
---|
32 | : CbcConsequence() |
---|
33 | , numberStates_(0) |
---|
34 | , states_(NULL) |
---|
35 | , startLower_(NULL) |
---|
36 | , startUpper_(NULL) |
---|
37 | , newBound_(NULL) |
---|
38 | , variable_(NULL) |
---|
39 | { |
---|
40 | } |
---|
41 | |
---|
42 | // One useful Constructor |
---|
43 | CbcFixVariable::CbcFixVariable(int numberStates, const int *states, const int *numberNewLower, |
---|
44 | const int **newLowerValue, |
---|
45 | const int **lowerColumn, |
---|
46 | const int *numberNewUpper, const int **newUpperValue, |
---|
47 | const int **upperColumn) |
---|
48 | : CbcConsequence() |
---|
49 | , states_(NULL) |
---|
50 | , startLower_(NULL) |
---|
51 | , startUpper_(NULL) |
---|
52 | , newBound_(NULL) |
---|
53 | , variable_(NULL) |
---|
54 | { |
---|
55 | // How much space |
---|
56 | numberStates_ = numberStates; |
---|
57 | if (numberStates_) { |
---|
58 | states_ = new int[numberStates_]; |
---|
59 | memcpy(states_, states, numberStates_ * sizeof(int)); |
---|
60 | int i; |
---|
61 | int n = 0; |
---|
62 | startLower_ = new int[numberStates_ + 1]; |
---|
63 | startUpper_ = new int[numberStates_ + 1]; |
---|
64 | startLower_[0] = 0; |
---|
65 | //count |
---|
66 | for (i = 0; i < numberStates_; i++) { |
---|
67 | n += numberNewLower[i]; |
---|
68 | startUpper_[i] = n; |
---|
69 | n += numberNewUpper[i]; |
---|
70 | startLower_[i + 1] = n; |
---|
71 | } |
---|
72 | newBound_ = new double[n]; |
---|
73 | variable_ = new int[n]; |
---|
74 | n = 0; |
---|
75 | for (i = 0; i < numberStates_; i++) { |
---|
76 | int j; |
---|
77 | int k; |
---|
78 | const int *bound; |
---|
79 | const int *variable; |
---|
80 | k = numberNewLower[i]; |
---|
81 | bound = newLowerValue[i]; |
---|
82 | variable = lowerColumn[i]; |
---|
83 | for (j = 0; j < k; j++) { |
---|
84 | newBound_[n] = bound[j]; |
---|
85 | variable_[n++] = variable[j]; |
---|
86 | } |
---|
87 | k = numberNewUpper[i]; |
---|
88 | bound = newUpperValue[i]; |
---|
89 | variable = upperColumn[i]; |
---|
90 | for (j = 0; j < k; j++) { |
---|
91 | newBound_[n] = bound[j]; |
---|
92 | variable_[n++] = variable[j]; |
---|
93 | } |
---|
94 | } |
---|
95 | } |
---|
96 | } |
---|
97 | |
---|
98 | // Copy constructor |
---|
99 | CbcFixVariable::CbcFixVariable(const CbcFixVariable &rhs) |
---|
100 | : CbcConsequence(rhs) |
---|
101 | { |
---|
102 | numberStates_ = rhs.numberStates_; |
---|
103 | states_ = NULL; |
---|
104 | startLower_ = NULL; |
---|
105 | startUpper_ = NULL; |
---|
106 | newBound_ = NULL; |
---|
107 | variable_ = NULL; |
---|
108 | if (numberStates_) { |
---|
109 | states_ = CoinCopyOfArray(rhs.states_, numberStates_); |
---|
110 | startLower_ = CoinCopyOfArray(rhs.startLower_, numberStates_ + 1); |
---|
111 | startUpper_ = CoinCopyOfArray(rhs.startUpper_, numberStates_ + 1); |
---|
112 | int n = startLower_[numberStates_]; |
---|
113 | newBound_ = CoinCopyOfArray(rhs.newBound_, n); |
---|
114 | variable_ = CoinCopyOfArray(rhs.variable_, n); |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | // Clone |
---|
119 | CbcConsequence * |
---|
120 | CbcFixVariable::clone() const |
---|
121 | { |
---|
122 | return new CbcFixVariable(*this); |
---|
123 | } |
---|
124 | |
---|
125 | // Assignment operator |
---|
126 | CbcFixVariable & |
---|
127 | CbcFixVariable::operator=(const CbcFixVariable &rhs) |
---|
128 | { |
---|
129 | if (this != &rhs) { |
---|
130 | CbcConsequence::operator=(rhs); |
---|
131 | delete[] states_; |
---|
132 | delete[] startLower_; |
---|
133 | delete[] startUpper_; |
---|
134 | delete[] newBound_; |
---|
135 | delete[] variable_; |
---|
136 | states_ = NULL; |
---|
137 | startLower_ = NULL; |
---|
138 | startUpper_ = NULL; |
---|
139 | newBound_ = NULL; |
---|
140 | variable_ = NULL; |
---|
141 | numberStates_ = rhs.numberStates_; |
---|
142 | if (numberStates_) { |
---|
143 | states_ = CoinCopyOfArray(rhs.states_, numberStates_); |
---|
144 | startLower_ = CoinCopyOfArray(rhs.startLower_, numberStates_ + 1); |
---|
145 | startUpper_ = CoinCopyOfArray(rhs.startUpper_, numberStates_ + 1); |
---|
146 | int n = startLower_[numberStates_]; |
---|
147 | newBound_ = CoinCopyOfArray(rhs.newBound_, n); |
---|
148 | variable_ = CoinCopyOfArray(rhs.variable_, n); |
---|
149 | } |
---|
150 | } |
---|
151 | return *this; |
---|
152 | } |
---|
153 | |
---|
154 | // Destructor |
---|
155 | CbcFixVariable::~CbcFixVariable() |
---|
156 | { |
---|
157 | delete[] states_; |
---|
158 | delete[] startLower_; |
---|
159 | delete[] startUpper_; |
---|
160 | delete[] newBound_; |
---|
161 | delete[] variable_; |
---|
162 | } |
---|
163 | // Set up a startLower for a single member |
---|
164 | void CbcFixVariable::applyToSolver(OsiSolverInterface *solver, int state) const |
---|
165 | { |
---|
166 | assert(state == -9999 || state == 9999); |
---|
167 | // Find state |
---|
168 | int find; |
---|
169 | for (find = 0; find < numberStates_; find++) |
---|
170 | if (states_[find] == state) |
---|
171 | break; |
---|
172 | if (find == numberStates_) |
---|
173 | return; |
---|
174 | int i; |
---|
175 | // Set new lower bounds |
---|
176 | for (i = startLower_[find]; i < startUpper_[find]; i++) { |
---|
177 | int iColumn = variable_[i]; |
---|
178 | double value = newBound_[i]; |
---|
179 | double oldValue = solver->getColLower()[iColumn]; |
---|
180 | //printf("for %d old lower bound %g, new %g",iColumn,oldValue,value); |
---|
181 | solver->setColLower(iColumn, CoinMax(value, oldValue)); |
---|
182 | //printf(" => %g\n",solver->getColLower()[iColumn]); |
---|
183 | } |
---|
184 | // Set new upper bounds |
---|
185 | for (i = startUpper_[find]; i < startLower_[find + 1]; i++) { |
---|
186 | int iColumn = variable_[i]; |
---|
187 | double value = newBound_[i]; |
---|
188 | double oldValue = solver->getColUpper()[iColumn]; |
---|
189 | //printf("for %d old upper bound %g, new %g",iColumn,oldValue,value); |
---|
190 | solver->setColUpper(iColumn, CoinMin(value, oldValue)); |
---|
191 | //printf(" => %g\n",solver->getColUpper()[iColumn]); |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 |
---|
196 | */ |
---|