cutbuffer.inc

Go to the documentation of this file.
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         // sort the buffered items
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         // reorder the buffered items
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     // unlock the buffered items
00197     for (int i = 0; i < n_; i++)
00198       psRef_[i]->conVar()->unlock();
00199 
00200     // determine the number of items to extract
00201     int nExtract;
00202 
00203     if (n_ < max) nExtract = n_;
00204     else          nExtract = max;
00205 
00206     // delete the nonextracted items  
00207     /* We have to check if the constraint/variable can be deleted, because the
00208      * pool slot might be shared with another constraint/variable that is not 
00209      * deleted.
00210      *
00211      * The deletion of the extracted items must be performed before the
00212      * deletion of the non-extracted ones. Otherwise if a \a NONDUPLPOOL
00213      * is used, it can happen that a constraint is removed from the pool 
00214      * that is the duplicate of an extracted one. 
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        // extract the items
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       // allow ranking in next iteration
00244       ranking_ = true;
00245 
00246     }
00247   
00248   
00249   
00250       
00251 #endif // ABA_CUTBUFFER_INC

Generated on Tue Aug 14 18:09:53 2007 for ABACUS by  doxygen 1.5.1