1 | /* $Id: CoinPostsolveMatrix.cpp 1373 2011-01-03 23:57:44Z lou $ */ |
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 | #include <stdio.h> |
7 | |
8 | #include <cassert> |
9 | #include <iostream> |
10 | |
11 | #include "CoinHelperFunctions.hpp" |
12 | #include "CoinPresolveMatrix.hpp" |
13 | |
14 | #if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY |
15 | #include "CoinPresolvePsdebug.hpp" |
16 | #endif |
17 | |
18 | /*! \file |
19 | |
20 | This file contains methods for CoinPostsolveMatrix, the object used during |
21 | postsolve transformations. |
22 | */ |
23 | |
24 | /* |
25 | Constructor and destructor for CoinPostsolveMatrix. |
26 | */ |
27 | |
28 | /* |
29 | Default constructor |
30 | |
31 | Postpone allocation of space until we actually load the object. |
32 | */ |
33 | |
34 | CoinPostsolveMatrix::CoinPostsolveMatrix |
35 | (int ncols_alloc, int nrows_alloc, CoinBigIndex nelems_alloc) |
36 | |
37 | : CoinPrePostsolveMatrix(ncols_alloc,nrows_alloc,nelems_alloc), |
38 | free_list_(0), |
39 | maxlink_(nelems_alloc), |
40 | link_(0), |
41 | cdone_(0), |
42 | rdone_(0) |
43 | |
44 | { /* nothing to do here */ |
45 | |
46 | return ; } |
47 | |
48 | /* |
49 | Destructor |
50 | */ |
51 | |
52 | CoinPostsolveMatrix::~CoinPostsolveMatrix() |
53 | |
54 | { delete[] link_ ; |
55 | |
56 | delete[] cdone_ ; |
57 | delete[] rdone_ ; |
58 | |
59 | return ; } |
60 | |
61 | /* |
62 | This routine loads a CoinPostsolveMatrix object from a CoinPresolveMatrix |
63 | object. The CoinPresolveMatrix object will be stripped, its components |
64 | transferred to the CoinPostsolveMatrix object, and the empty shell of the |
65 | CoinPresolveObject will be destroyed. |
66 | |
67 | The routine expects an empty CoinPostsolveMatrix object, and will leak |
68 | any memory already allocated. |
69 | */ |
70 | |
71 | void |
72 | CoinPostsolveMatrix::assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) |
73 | |
74 | { |
75 | /* |
76 | Start with simple data --- allocated and current size. |
77 | */ |
78 | ncols0_ = preObj->ncols0_ ; |
79 | nrows0_ = preObj->nrows0_ ; |
80 | nelems0_ = preObj->nelems0_ ; |
81 | bulk0_ = preObj->bulk0_ ; |
82 | |
83 | ncols_ = preObj->ncols_ ; |
84 | nrows_ = preObj->nrows_ ; |
85 | nelems_ = preObj->nelems_ ; |
86 | /* |
87 | Now bring over the column-major matrix and other problem data. |
88 | */ |
89 | mcstrt_ = preObj->mcstrt_ ; |
90 | preObj->mcstrt_ = 0 ; |
91 | hincol_ = preObj->hincol_ ; |
92 | preObj->hincol_ = 0 ; |
93 | hrow_ = preObj->hrow_ ; |
94 | preObj->hrow_ = 0 ; |
95 | colels_ = preObj->colels_ ; |
96 | preObj->colels_ = 0 ; |
97 | |
98 | cost_ = preObj->cost_ ; |
99 | preObj->cost_ = 0 ; |
100 | originalOffset_ = preObj->originalOffset_ ; |
101 | clo_ = preObj->clo_ ; |
102 | preObj->clo_ = 0 ; |
103 | cup_ = preObj->cup_ ; |
104 | preObj->cup_ = 0 ; |
105 | rlo_ = preObj->rlo_ ; |
106 | preObj->rlo_ = 0 ; |
107 | rup_ = preObj->rup_ ; |
108 | preObj->rup_ = 0 ; |
109 | |
110 | originalColumn_ = preObj->originalColumn_ ; |
111 | preObj->originalColumn_ = 0 ; |
112 | originalRow_ = preObj->originalRow_ ; |
113 | preObj->originalRow_ = 0 ; |
114 | |
115 | ztolzb_ = preObj->ztolzb_ ; |
116 | ztoldj_ = preObj->ztoldj_ ; |
117 | maxmin_ = preObj->maxmin_ ; |
118 | /* |
119 | Now the problem solution. Often this will be empty, but that's not a problem. |
120 | */ |
121 | sol_ = preObj->sol_ ; |
122 | preObj->sol_ = 0 ; |
123 | rowduals_ = preObj->rowduals_ ; |
124 | preObj->rowduals_ = 0 ; |
125 | acts_ = preObj->acts_ ; |
126 | preObj->acts_ = 0 ; |
127 | rcosts_ = preObj->rcosts_ ; |
128 | preObj->rcosts_ = 0 ; |
129 | colstat_ = preObj->colstat_ ; |
130 | preObj->colstat_ = 0 ; |
131 | rowstat_ = preObj->rowstat_ ; |
132 | preObj->rowstat_ = 0 ; |
133 | /* |
134 | The CoinPostsolveMatrix comes with messages and a handler, but replace them |
135 | with the versions from the CoinPresolveObject, in case they've been |
136 | customized. Let preObj believe it's no longer responsible for the handler. |
137 | */ |
138 | if (defaultHandler_ == true) |
139 | delete handler_ ; |
140 | handler_ = preObj->handler_ ; |
141 | preObj->defaultHandler_ = false ; |
142 | messages_ = preObj->messages_ ; |
143 | /* |
144 | Initialise the postsolve portions of this object. Which amounts to setting |
145 | up the thread links to match the column-major matrix representation. This |
146 | would be trivial except that the presolve matrix is loosely packed. We can |
147 | either compress the matrix, or record the existing free space pattern. Bet |
148 | that the latter is more efficient. Remember that mcstrt_[ncols_] actually |
149 | points to the end of the bulk storage area, so when we process the last |
150 | column in the bulk storage area, we'll add the free space block at the end |
151 | of bulk storage to the free list. |
152 | |
153 | We need to allow for a 0x0 matrix here --- a pathological case, but it slips |
154 | in when (for example) confirming a solution in an ILP code. |
155 | */ |
156 | free_list_ = NO_LINK ; |
157 | maxlink_ = bulk0_ ; |
158 | link_ = new CoinBigIndex [maxlink_] ; |
159 | |
160 | if (ncols_ > 0) |
161 | { CoinBigIndex minkcs = -1 ; |
162 | for (int j = 0 ; j < ncols_ ; j++) |
163 | { CoinBigIndex kcs = mcstrt_[j] ; |
164 | int lenj = hincol_[j] ; |
165 | assert(lenj > 0) ; |
166 | CoinBigIndex kce = kcs+lenj-1 ; |
167 | CoinBigIndex k ; |
168 | |
169 | for (k = kcs ; k < kce ; k++) |
170 | { link_[k] = k+1 ; } |
171 | link_[k++] = NO_LINK ; |
172 | |
173 | if (preObj->clink_[j].pre == NO_LINK) |
174 | { minkcs = kcs ; } |
175 | int nxtj = preObj->clink_[j].suc ; |
176 | assert(nxtj >= 0 && nxtj <= ncols_) ; |
177 | CoinBigIndex nxtcs = mcstrt_[nxtj] ; |
178 | for ( ; k < nxtcs ; k++) |
179 | { link_[k] = free_list_ ; |
180 | free_list_ = k ; } } |
181 | |
182 | assert(minkcs >= 0) ; |
183 | if (minkcs > 0) |
184 | { for (CoinBigIndex k = 0 ; k < minkcs ; k++) |
185 | { link_[k] = free_list_ ; |
186 | free_list_ = k ; } } } |
187 | else |
188 | { for (CoinBigIndex k = 0 ; k < maxlink_ ; k++) |
189 | { link_[k] = free_list_ ; |
190 | free_list_ = k ; } } |
191 | /* |
192 | That's it, preObj can die now. |
193 | */ |
194 | delete preObj ; |
195 | preObj = 0 ; |
196 | |
197 | # if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY |
198 | /* |
199 | These are used to track the action of postsolve transforms during debugging. |
200 | */ |
201 | cdone_ = new char [ncols0_] ; |
202 | CoinFillN(cdone_,ncols_,PRESENT_IN_REDUCED) ; |
203 | CoinZeroN(cdone_+ncols_,ncols0_-ncols_) ; |
204 | rdone_ = new char [nrows0_] ; |
205 | CoinFillN(rdone_,nrows_,PRESENT_IN_REDUCED) ; |
206 | CoinZeroN(rdone_+nrows_,nrows0_-nrows_) ; |
207 | # else |
208 | cdone_ = 0 ; |
209 | rdone_ = 0 ; |
210 | # endif |
211 | |
212 | # if PRESOLVE_CONSISTENCY |
213 | presolve_check_free_list(this,true) ; |
214 | presolve_check_threads(this) ; |
215 | # endif |
216 | |
217 | return ; } |
218 | |