00001
00029 #ifndef ABA_CUTBUFFER_INC
00030 #define ABA_CUTBUFFER_INC
00031
00032 #include "abacus/poolslotref.h"
00033 #include "abacus/poolslot.h"
00034 #include "abacus/cutbuffer.h"
00035 #include "abacus/master.h"
00036 #include "abacus/variable.h"
00037 #include "abacus/constraint.h"
00038 #include "abacus/sorter.h"
00039
00040 template<class BaseType, class CoType>
00041 ABA_CUTBUFFER<BaseType, CoType>::ABA_CUTBUFFER(ABA_MASTER *master, int size)
00042 :
00043 master_(master),
00044 n_(0),
00045 psRef_(master, size),
00046 keepInPool_(master, size),
00047 rank_(master, size),
00048 ranking_(true)
00049 { }
00050
00051 template<class BaseType, class CoType>
00052 ABA_CUTBUFFER<BaseType, CoType>::~ABA_CUTBUFFER()
00053 {
00054 for (int i = 0; i < n_; i++) {
00055 psRef_[i]->conVar()->unlock();
00056 delete psRef_[i];
00057 }
00058 }
00059
00060 template<class BaseType, class CoType>
00061 inline int ABA_CUTBUFFER<BaseType, CoType>::size() const
00062 {
00063 return psRef_.size();
00064 }
00065
00066 template<class BaseType, class CoType>
00067 inline int ABA_CUTBUFFER<BaseType, CoType>::number() const
00068 {
00069 return n_;
00070 }
00071
00072 template<class BaseType, class CoType>
00073 inline int ABA_CUTBUFFER<BaseType, CoType>::space() const
00074 {
00075 return size() - n_;
00076 }
00077
00078 template<class BaseType, class CoType>
00079 inline ABA_POOLSLOT<BaseType, CoType> * ABA_CUTBUFFER<BaseType, CoType>::slot(int i)
00080 {
00081 return psRef_[i]->slot();
00082 }
00083
00084 template<class BaseType, class CoType>
00085 int ABA_CUTBUFFER<BaseType, CoType>::insert(ABA_POOLSLOT<BaseType, CoType> *slot,
00086 bool keepInPool)
00087 {
00088 if (n_ == size())
00089 return 1;
00090 else {
00091 psRef_[n_] = new ABA_POOLSLOTREF<BaseType, CoType>(slot);
00092 keepInPool_[n_] = keepInPool;
00093 ranking_ = false;
00094 slot->conVar()->lock();
00095 ++n_;
00096 return 0;
00097 }
00098 }
00099
00100 template<class BaseType, class CoType>
00101 int ABA_CUTBUFFER<BaseType, CoType>::insert(ABA_POOLSLOT<BaseType, CoType> *slot,
00102 bool keepInPool,
00103 double rank)
00104 {
00105 if (n_ == size())
00106 return 1;
00107 else {
00108 psRef_[n_] = new ABA_POOLSLOTREF<BaseType, CoType>(slot);
00109 keepInPool_[n_] = keepInPool;
00110 rank_[n_] = rank;
00111 ++n_;
00112 slot->conVar()->lock();
00113 return 0;
00114 }
00115 }
00116
00117 template<class BaseType, class CoType>
00118 void ABA_CUTBUFFER<BaseType, CoType>::remove(ABA_BUFFER<int> &index)
00119 {
00120
00121 ABA_POOLSLOT<BaseType, CoType> *ps;
00122 ABA_POOLSLOTREF<BaseType, CoType> *psr;
00123
00124 const int nIndex = index.number();
00125
00126 for (int i = 0; i < nIndex; i++) {
00127 psr = psRef_[index[i]];
00128 psr->conVar()->unlock();
00129 ps = psr->slot();
00130 delete psr;
00131 if (ps->conVar()->deletable())
00132 ps->removeConVarFromPool();
00133 }
00134 psRef_.leftShift(index);
00135 keepInPool_.leftShift(index);
00136 rank_.leftShift(index);
00137
00138 n_ -= nIndex;
00139 }
00140
00141 template<class BaseType, class CoType>
00142 void ABA_CUTBUFFER<BaseType, CoType>::sort(int threshold)
00143 {
00144 if (ranking_) {
00145 if (n_ > threshold) {
00146
00147 ABA_SORTER<int, double> sorter(master_);
00148 ABA_ARRAY<int> index(master_, n_);
00149 ABA_ARRAY<double> keys(master_, n_);
00150
00151 for (int i = 0; i < n_; i++) {
00152 index[i] = i;
00153 keys[i] = -rank_[i];
00154 }
00155
00156 sorter.quickSort(n_, index, keys);
00157
00158
00159 ABA_ARRAY<ABA_POOLSLOTREF<BaseType, CoType>*> psRefSorted(master_, n_);
00160 ABA_ARRAY<bool> keepInPoolSorted(master_, n_);
00161
00162 #ifdef ABACUS_NO_FOR_SCOPE
00163 for (i = 0; i < n_; i++) {
00164 #else
00165 for (int i = 0; i < n_; i++) {
00166 #endif
00167 psRefSorted[i] = psRef_[index[i]];
00168 keepInPoolSorted[i] = keepInPool_[index[i]];
00169 }
00170
00171 #ifdef ABACUS_NO_FOR_SCOPE
00172 for (i = 0; i < n_; i++) {
00173 #else
00174 for (int i = 0; i < n_; i++) {
00175 #endif
00176 psRef_[i] = psRefSorted[i];
00177 keepInPool_[i] = keepInPoolSorted[i];
00178 }
00179
00180 ABA_CUTBUFFER<BaseType, CoType>::master_->out(1) << "items ranked: accepted in " << -keys[0] << " ... ";
00181 ABA_CUTBUFFER<BaseType, CoType>::master_->out() << -keys[threshold - 1] << ", rejected in ";
00182 ABA_CUTBUFFER<BaseType, CoType>::master_->out() << -keys[threshold] << " ... " << -keys[n_ - 1] << endl;
00183
00184 }
00185 else
00186 ABA_CUTBUFFER<BaseType, CoType>::master_->out(1) << "not enough items, no ranking required" << endl;
00187 }
00188 else
00189 ABA_CUTBUFFER<BaseType, CoType>::master_->out(1) << "ranking of buffered items not possible" << endl;
00190 }
00191
00192 template<class BaseType, class CoType>
00193 void ABA_CUTBUFFER<BaseType, CoType>::extract(int max,
00194 ABA_BUFFER<ABA_POOLSLOT<BaseType, CoType>*> &newSlots)
00195 {
00196
00197 for (int i = 0; i < n_; i++)
00198 psRef_[i]->conVar()->unlock();
00199
00200
00201 int nExtract;
00202
00203 if (n_ < max) nExtract = n_;
00204 else nExtract = max;
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 ABA_POOLSLOT<BaseType, CoType> *s;
00217
00218 #ifdef ABACUS_NO_FOR_SCOPE
00219 for (i = nExtract; i < n_; i++)
00220 #else
00221 for (int i = nExtract; i < n_; i++)
00222 #endif
00223 if (!keepInPool_[i]) {
00224 s = psRef_[i]->slot();
00225 delete psRef_[i];
00226 if (s->conVar()->deletable())
00227 s->removeConVarFromPool();
00228 }
00229 else delete psRef_[i];
00230
00231 n_ = 0;
00232
00233
00234 #ifdef ABACUS_NO_FOR_SCOPE
00235 for (i = 0; i < nExtract; i++) {
00236 #else
00237 for (int i = 0; i < nExtract; i++) {
00238 #endif
00239 newSlots.push(psRef_[i]->slot());
00240 delete psRef_[i];
00241 }
00242
00243
00244 ranking_ = true;
00245
00246 }
00247
00248
00249
00250
00251 #endif // ABA_CUTBUFFER_INC