00001
00029 #ifndef ABA_STANDARDPOOL_INC
00030 #define ABA_STANDARDPOOL_INC
00031
00032 #include "abacus/cutbuffer.h"
00033 #include "abacus/master.h"
00034 #include "abacus/poolslot.h"
00035 #include "abacus/constraint.h"
00036 #include "abacus/variable.h"
00037 #include "abacus/sub.h"
00038 #include "abacus/bheap.h"
00039
00040 #include <iostream>
00041 using namespace std;
00042
00043 #ifdef ABACUS_PARALLEL
00044 #include "abacus/message.h"
00045 #include "abacus/id.h"
00046 #include "abacus/debug.h"
00047 #endif
00048
00049 template<class BaseType, class CoType>
00050 ABA_STANDARDPOOL<BaseType, CoType>::ABA_STANDARDPOOL(ABA_MASTER *master,
00051 int size,
00052 bool autoRealloc)
00053 :
00054 ABA_POOL<BaseType, CoType>(master),
00055 pool_(master, size),
00056 freeSlots_(master),
00057 autoRealloc_(autoRealloc)
00058 {
00059 for (int i = 0; i < size; i++) {
00060 pool_[i] = new ABA_POOLSLOT<BaseType, CoType>(master, this);
00061 freeSlots_.appendTail(pool_[i]);
00062 }
00063 }
00064
00065 template<class BaseType, class CoType>
00066 ABA_STANDARDPOOL<BaseType, CoType>::~ABA_STANDARDPOOL()
00067 {
00068 const int s = size();
00069
00070 for (int i = 0; i < s; i++) delete pool_[i];
00071 }
00072
00073
00074 #ifdef ABACUS_PARALLEL
00075 #if 0 // currently not used
00076
00077 template<class BaseType, class CoType>
00078 ABA_STANDARDPOOL<BaseType, CoType>::ABA_STANDARDPOOL(ABA_MASTER *master, ABA_MESSAGE &msg)
00079 :
00080 ABA_POOL<BaseType, CoType>(master),
00081 pool_(master, msg.unpackInt()),
00082 freeSlots_(master)
00083 {
00084 msg.unpack(autoRealloc_);
00085
00086 int size = pool_.size();
00087 for (int i = 0; i < size; i++) {
00088 pool_[i] = new ABA_POOLSLOT<BaseType, CoType>(master, this);
00089 freeSlots_.appendTail(pool_[i]);
00090 }
00091
00092 int number;
00093 msg.unpack(number);
00094 for (int i = 0; i < number; i++) {
00095 ABA_ID id(msg);
00096 int classId;
00097 msg.unpack(classId);
00098 BaseType *cv = (BaseType*) master_->unpackConVar(msg, classId);
00099 ABA_POOLSLOT<BaseType, CoType>* slot = insert(cv);
00100 if (slot == 0) {
00101 master_->err() << "ABA_STANDARDPOOL::ABA_STANDARDPOOL(): could not"
00102 " insert the constraint/variable in message"
00103 " constructor." << endl;
00104 exit(Fatal);
00105 }
00106 if (id.isInitialized())
00107 slot->setIdentification(id);
00108 }
00109 }
00110
00111 template<class BaseType, class CoType>
00112 void ABA_STANDARDPOOL<BaseType, CoType>::pack(ABA_MESSAGE &msg) const
00113 {
00114 int size = pool_.size();
00115 msg.pack(size);
00116 msg.pack(autoRealloc_);
00117 msg.pack(number_);
00118 int n = 0;
00119 for (int i = 0; i < size; i++) {
00120 BaseType *cv = pool_[i]->conVar();
00121 if (cv) {
00122 pool_[i]->getIdentification().pack(msg);
00123 msg.pack(cv->classId());
00124 cv->pack(msg);
00125 n++;
00126 }
00127 }
00128 if (n != number_) {
00129 master_->err() << "ABA_STANDARDPOOL::pack(): non void slots = " << n
00130 << ", should be " << number_ << "." << endl;
00131 exit(Fatal);
00132 }
00133 }
00134
00135 #endif // #if 0
00136 #endif
00137
00138 template<class BaseType, class CoType>
00139 ostream &operator<<(ostream &out, const ABA_STANDARDPOOL<BaseType, CoType> &rhs)
00140 {
00141 const int s = rhs.size();
00142
00143 for (int i = 0; i < s; i++)
00144 if (rhs.pool_[i]->conVar()) {
00145 out << i << ": ";
00146 rhs.pool_[i]->conVar()->print(out);
00147 out << endl;
00148 }
00149
00150 return out;
00151 }
00152
00153 template<class BaseType, class CoType>
00154 ABA_POOLSLOT<BaseType, CoType> * ABA_STANDARDPOOL<BaseType, CoType>::insert(
00155 BaseType *cv)
00156 {
00157 ABA_POOLSLOT<BaseType, CoType>* slot = getSlot();
00158 if (slot == 0) {
00159 if(cleanup() == 0) {
00160 if (autoRealloc_)
00161 increase((int) (size()*1.1 + 1));
00162 else {
00163 if (removeNonActive(size()/10 + 1) == 0)
00164 return 0;
00165 }
00166 }
00167 slot = getSlot();
00168 }
00169
00170 slot->insert(cv);
00171 ++ABA_POOL<BaseType, CoType>::number_;
00172 return slot;
00173 }
00174
00175 template<class BaseType, class CoType>
00176 void ABA_STANDARDPOOL<BaseType, CoType>::increase(int size)
00177 {
00178 int oldSize = pool_.size();
00179
00180 if (size < oldSize) {
00181 ABA_POOL<BaseType, CoType>::master_->err() << "ABA_STANDARDPOOL::increase(): the pool size cannot be decreased." << endl;
00182 exit(ABA_ABACUSROOT::Fatal);
00183 }
00184
00185 pool_.realloc(size);
00186
00187 for(int i = oldSize; i < size; i++) {
00188 pool_[i] = new ABA_POOLSLOT<BaseType, CoType>(ABA_POOL<BaseType, CoType>::master_, this);
00189 freeSlots_.appendTail(pool_[i]);
00190 }
00191 }
00192
00193 template<class BaseType, class CoType>
00194 int ABA_STANDARDPOOL<BaseType, CoType>::cleanup()
00195 {
00196 int nDeleted = 0;
00197
00198 for(int i = 0; i < ABA_POOL<BaseType, CoType>::number(); i++)
00199 {
00200 if(softDeleteConVar(pool_[i]) == 0)
00201 {
00202 nDeleted++;
00203
00204
00205 if (i != ABA_POOL<BaseType, CoType>::number())
00206 {
00207
00208 ABA_POOLSLOT<BaseType, CoType> *CMslot = pool_[i];
00209 pool_[i] = pool_[ABA_POOL<BaseType, CoType>::number()];
00210 pool_[ABA_POOL<BaseType, CoType>::number()] = CMslot;
00211 i--;
00212 }
00213 }
00214 }
00215
00216 ABA_POOL<BaseType, CoType>::master_->out() << "ABA_STANDARDPOOL::cleanup(): " << nDeleted << " items removed." << endl;
00217 return nDeleted;
00218
00219 }
00220
00221 template<class BaseType, class CoType>
00222 int ABA_STANDARDPOOL<BaseType, CoType>::removeNonActive(int maxRemove)
00223 {
00225 ABA_BUFFER<int> elems(ABA_POOL<BaseType, CoType>::master_, size());
00226 ABA_BUFFER<int> keys(ABA_POOL<BaseType, CoType>::master_, size());
00227 BaseType *cv;
00228
00229 const int s = size();
00230
00231 for (int i = 0; i < s; i++) {
00232 cv = pool_[i]->conVar();
00233 if (cv && !cv->active() && !cv->locked()) {
00234 elems.push(i);
00235 keys.push(cv->nReferences());
00236 }
00237 }
00238
00239 ABA_BHEAP<int, int> candidates(ABA_POOL<BaseType, CoType>::master_, elems, keys);
00240
00242
00245 int nRemoved = 0;
00246 int c;
00247
00248 while(nRemoved < maxRemove && !candidates.empty()) {
00249 c = candidates.extractMin();
00250 hardDeleteConVar(pool_[c]);
00251 nRemoved++;
00252 }
00253
00254 ABA_POOL<BaseType, CoType>::master_->out() << nRemoved << " inactive items removed from pool." << endl;
00255
00256 return nRemoved;
00257
00258 }
00259
00260 template<class BaseType, class CoType>
00261 inline int ABA_STANDARDPOOL<BaseType, CoType>::size() const
00262 {
00263 return pool_.size();
00264 }
00265
00266 template<class BaseType, class CoType>
00267 inline ABA_POOLSLOT<BaseType, CoType> *ABA_STANDARDPOOL<BaseType, CoType>::slot(int i)
00268 {
00269 return pool_[i];
00270 }
00271
00272 template<class BaseType, class CoType>
00273 inline ABA_POOLSLOT<BaseType, CoType>* ABA_STANDARDPOOL<BaseType, CoType>::getSlot()
00274 {
00275 ABA_POOLSLOT<BaseType, CoType> *slot;
00276
00277 if (freeSlots_.extractHead(slot)) return 0;
00278 return slot;
00279 }
00280
00281 template<class BaseType, class CoType>
00282 void ABA_STANDARDPOOL<BaseType, CoType>::putSlot(ABA_POOLSLOT<BaseType, CoType> *slot)
00283 {
00284 if (slot->conVar()) {
00285 ABA_POOL<BaseType, CoType>::master_->err() << "ABA_STANDARDPOOL::putSlot(): you cannot put a non-void slot." << endl;
00286 exit(ABA_ABACUSROOT::Fatal);
00287 }
00288 freeSlots_.appendHead(slot);
00289 }
00290
00291 template<class BaseType, class CoType>
00292 int ABA_STANDARDPOOL<BaseType, CoType>::separate(
00293 double *z,
00294 ABA_ACTIVE<CoType, BaseType> *active,
00295 ABA_SUB *sub,
00296 ABA_CUTBUFFER<BaseType, CoType> *cutBuffer,
00297 double minAbsViolation,
00298 int ranking)
00299 {
00300 BaseType *cv;
00301 double violation;
00302 int oldSep = cutBuffer->number();
00303
00304 ABA_POOL<BaseType, CoType>::master_->out() << "ABA_STANDARDPOOL::separate(): ";
00305 ABA_POOL<BaseType, CoType>::master_->out() << "size = " << size() << " n = " << ABA_POOL<BaseType, CoType>::number_;
00306
00307 ABA_POOLSLOT<BaseType, CoType> *slot;
00308 const int s = size();
00309
00310 for (int i = 0; i < s; i++) {
00311 slot = pool_[i];
00312 cv = slot->conVar();
00313 if (cv && !cv->active() && (cv->global() || cv->valid(sub)))
00314 if (cv->violated(active, z, &violation)
00315 && fabs(violation) > minAbsViolation) {
00316 if (ranking == 0) {
00317 if (cutBuffer->insert(slot, true))
00318 break;
00319 }
00320 else if (ranking == 1) {
00321 if (cutBuffer->insert(slot, true, violation))
00322 break;
00323 }
00324 else if (ranking == 2) {
00325 if (cutBuffer->insert(slot, true, fabs(violation)))
00326 break;
00327 }
00328 else if (ranking == 3) {
00329 if (cutBuffer->insert(slot, true, cv->rank()))
00330 break;
00331 }
00332 }
00333 }
00334
00335 ABA_POOL<BaseType, CoType>::master_->out() << " generated = " << cutBuffer->number() - oldSep << endl;
00336 #ifdef ABACUS_PARALLEL
00337 if (debug(DEBUG_SEPARATE)) {
00338 for (int i=oldSep; i<cutBuffer->number(); i++) {
00339 ABA_POOLSLOT<BaseType, CoType> *ps = cutBuffer->slot(i);
00340 master_->out() << "DEBUG_SEPARATE: cv=" << ps->getIdentification() << endl;
00341 }
00342 }
00343 #endif
00344 return cutBuffer->number() - oldSep;
00345 }
00346
00347 #endif // ABA_STANDARDPOOL_INC