00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifndef SCV_BAG_H
00045 #define SCV_BAG_H
00046
00047 #include "scv/scv_config.h"
00048 #include <stdlib.h>
00049 #include <algorithm>
00050 #include <assert.h>
00051 #include <string>
00052 #include <list>
00053 #include "scv/scv_random.h"
00054 #include "scv/scv_util.h"
00055 #include "scv/scv_report.h"
00056
00057
00058
00059
00060
00061
00062 template <class T>
00063 class _scv_bag_record {
00064 private:
00065 T _element;
00066 int _totalCount;
00067 int _unmarkedCount;
00068 public:
00069
00070 _scv_bag_record() : _element(T()), _totalCount(1), _unmarkedCount(1) { }
00071 _scv_bag_record(const T& arg, const int count=1) : _element(arg),
00072 _totalCount(count), _unmarkedCount(count) { }
00073 _scv_bag_record(const _scv_bag_record& other) : _element(other._element),
00074 _totalCount(other._totalCount), _unmarkedCount(other._unmarkedCount) {}
00075
00076
00077 ~_scv_bag_record() {} ;
00078
00079
00080 T& element() { return _element; }
00081 const T& element() const { return _element; }
00082 int count() const { return _totalCount; }
00083 int uCount() const { return _unmarkedCount; }
00084 int mCount() const { return _totalCount - _unmarkedCount; }
00085
00086
00087
00088
00089 void popCount(bool marked, bool All, int& size, int& umarkSize, int& peekuCount, int& peekmCount) {
00090 if (All) {
00091 size -= _totalCount ;
00092 umarkSize -= _unmarkedCount ;
00093 _totalCount = 0 ;
00094 _unmarkedCount = 0;
00095 peekuCount = 0;
00096 peekmCount = 0;
00097 } else {
00098 if (marked && mCount()) --peekmCount;
00099 else if (!marked && uCount()) {
00100 --_unmarkedCount ;
00101 --umarkSize;
00102 --peekuCount;
00103 } else if (!marked) {
00104 _scv_message::message(_scv_message::BAG_ZERO_UNMARKED_OBJECTS,"pop");
00105 } else if (marked) {
00106 _scv_message::message(_scv_message::BAG_ZERO_MARKED_OBJECTS,"pop");
00107 }
00108 --_totalCount; --size ;
00109 }
00110 }
00111
00112
00113 int markElement(bool All = false ) {
00114 if (All) {
00115 int count = _unmarkedCount ;
00116 _unmarkedCount = 0 ;
00117 return count ;
00118 }
00119 else if (_unmarkedCount > 0) {
00120 _unmarkedCount--;
00121 return 1 ;
00122 } else return 0 ;
00123 }
00124
00125 int unmarkElement(bool All = false) {
00126 if (All) {
00127 int mcount = _totalCount - _unmarkedCount ;
00128 _unmarkedCount = _totalCount;
00129 return mcount ;
00130 }
00131 else if (_unmarkedCount < _totalCount) {
00132 _unmarkedCount++ ;
00133 return 1 ;
00134 } else return 0 ;
00135 }
00136
00137 bool is_equal(const _scv_bag_record& other) const ;
00138
00139 void print(ostream& o=scv_out, int details=0, int indent=0) const;
00140 };
00141
00142 template <class T>
00143 bool _scv_bag_record<T>::is_equal(const _scv_bag_record<T>& other) const {
00144 return (this->_element == other._element) ;
00145 }
00146
00147 template <class T>
00148 bool operator==(const _scv_bag_record<T>& a, const _scv_bag_record<T>& b){
00149 return (a.is_equal(b));
00150 }
00151
00152
00153 #include "scv/_scv_list_iter.h"
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 template <class T>
00175 class scv_bag : public _scv_data_structure {
00176 typedef int (*priorityFuncT)(const T&, const T&);
00177 public:
00178 virtual const char *kind() const
00179 { static const char *name="scv_bag"; return name; }
00180
00181 private:
00182 typedef typename list<_scv_bag_record<T> >::iterator _bIterT;
00183 typedef typename list<_scv_bag_record<T> >::const_iterator _bCIterT;
00184 typedef scv_peek_bag_iter<T > peekIterT;
00185
00186 list<_scv_bag_record<T> > _bag;
00187 int _size;
00188 int _dsize;
00189 int _unmarkedSize;
00190
00191 mutable bool _lastPeekIsMarked;
00192 mutable bool _lastPeekValid;
00193 mutable peekIterT _lastPeek;
00194 mutable bool _randMode ;
00195 mutable bool _rlock ;
00196 mutable bool _randomOwner;
00197 unsigned long _seed;
00198 scv_random* _randomP;
00199
00200 inline void incPeek() const {
00201 ++_lastPeek;
00202 if (_lastPeek.peek() == ((scv_bag*) this)->_bag.end())
00203 _lastPeek.peek() = ((scv_bag*) this)->_bag.begin();
00204 }
00205
00206
00207 inline void dIncPeek() const {
00208 _lastPeek.dInc();
00209 if (_lastPeek.peek() == ((scv_bag*) this)->_bag.end())
00210 _lastPeek.peek() = ((scv_bag*) this)->_bag.begin();
00211 }
00212
00213
00214
00215 inline void nPeek0(bool distinct = false) const {
00216 if (!_lastPeekValid) {
00217 _lastPeek.peek() = ((scv_bag*) this)->_bag.begin();
00218 _lastPeek.lInitCount();
00219 } else if (distinct) dIncPeek();
00220 }
00221
00222
00223 inline void nextPeek(bool distinct= false) const {
00224 nPeek0(distinct);
00225 incPeek();
00226 }
00227
00228
00229
00230 inline void markedPeek(bool distinct) const {
00231 nPeek0(distinct);
00232 while( _lastPeek.mObjCount() >= (*_lastPeek).mCount()) dIncPeek();
00233
00234 (_lastPeek.mObjCount())++ ;
00235
00236 }
00237
00238
00239 inline void unmarkedPeek(bool distinct) const {
00240 nPeek0(distinct);
00241
00242 while( _lastPeek.uObjCount() >= (*_lastPeek).uCount()) dIncPeek();
00243
00244 (_lastPeek.uObjCount())++ ;
00245
00246 }
00247
00248 inline void decPeek() const {
00249 if (_lastPeek.peek() == ((scv_bag*) this)->_bag.begin())
00250 _lastPeek.peek() = ((scv_bag*) this)->_bag.end();
00251 --_lastPeek;
00252 }
00253
00254 inline void dDecPeek() const {
00255 if (_lastPeek.peek() == ((scv_bag*) this)->_bag.begin())
00256 _lastPeek.peek() = ((scv_bag*) this)->_bag.end();
00257 _lastPeek.dDec();
00258 }
00259
00260
00261
00262
00263 inline void prevPeek(bool distinct=false) const {
00264 if (_lastPeekValid) if (distinct) dDecPeek(); else decPeek();
00265 else {
00266 _lastPeek.peek() = ((scv_bag*) this)->_bag.begin();
00267 _lastPeek.lInitCount();
00268 }
00269 }
00270
00271
00272
00273
00274
00275 void _bagErase() {
00276
00277 if (_lastPeekValid) {
00278
00279 _lastPeekIsMarked = false;
00280 _unmarkedSize -= ((*_lastPeek).uCount());
00281 _size -= ((*_lastPeek).count());
00282 --_dsize;
00283
00284 if (_randMode || _size == 0 ||
00285 _lastPeek.peek() == _bag.begin()) {
00286 _bag.erase(_lastPeek.modify());
00287 _lastPeekValid = false ;
00288 } else {
00289 _bIterT eraseIter = _lastPeek.modify() ;
00290 dDecPeek();
00291 _bag.erase(eraseIter);
00292 }
00293 } else {
00294 _scv_message::message(_scv_message::BAG_INVALID_PEEK_ERASE,nameP());
00295 }
00296
00297 }
00298
00299
00300
00301 public:
00302
00303
00304
00305
00306
00307
00308
00309 scv_bag(const char *nameP="<anonymous>",
00310 unsigned long seed = 0) :
00311 _scv_data_structure(nameP),
00312 _bag(),
00313 _size(0),
00314 _dsize(0),
00315 _unmarkedSize(0),
00316 _lastPeekValid(false),
00317 _randMode(true),
00318 _rlock(true),
00319 _randomOwner(false),
00320 _seed(seed),
00321 _randomP(NULL) {
00322 }
00323
00324 scv_bag(const scv_bag& other, const char *nameP="<anonymous>") :
00325 _scv_data_structure(nameP),
00326 _bag(other._bag),
00327 _size(other._size),
00328 _dsize(other._dsize),
00329 _unmarkedSize(other._unmarkedSize),
00330 _lastPeekValid(other._lastPeekValid),
00331 _lastPeek(other._lastPeek),
00332 _randMode(true),
00333 _rlock(true),
00334 _randomOwner(other._randomOwner),
00335 _seed(other._seed),
00336 _randomP(_randomP) {
00337 if (_randomOwner)
00338 _randomP = new scv_random(*other._randomP);
00339 }
00340
00341 scv_bag& operator=(const scv_bag& other) {
00342 if (this != &other) {
00343 _bag = other._bag;
00344 _size = other._size;
00345 _dsize = other._dsize;
00346 _unmarkedSize = other._unmarkedSize;
00347 _lastPeekValid = other._lastPeekValid;
00348 _lastPeek = other._lastPeek;
00349 _randMode= other._randMode;
00350 _rlock = other._rlock;
00351 }
00352 return *this;
00353 }
00354
00355
00356
00357
00358 ~scv_bag() {}
00359
00360
00361
00362
00363
00364 int size() const { return _size; }
00365
00366
00367
00368
00369 bool empty() const { return _size == 0; }
00370
00371
00372
00373
00374
00375 int unMarkedSize() const { return _unmarkedSize; }
00376 int unmarked_size() const { return _unmarkedSize; }
00377 int uSize() const {return _unmarkedSize; }
00378
00379 int mSize() const { return _size - _unmarkedSize; }
00380 int markedSize() const { return _size - _unmarkedSize; }
00381 int marked_size() const { return _size - _unmarkedSize; }
00382
00383 int dSize() const { return _dsize; }
00384 int distinctSize() const { return _dsize; }
00385 int distinct_size() const { return _dsize; }
00386
00387
00388 void resetPeek () const {
00389 _lastPeekValid = false;
00390 _lastPeekIsMarked = false;
00391 _rlock = false ;
00392 _randMode = true ;
00393 }
00394 void reset_peek () const {
00395 resetPeek();
00396 }
00397 bool validPeek() const { return _lastPeekValid ; }
00398 bool valid_peek() const { return _lastPeekValid ; }
00399
00400 const T& peek() const {
00401 if (_lastPeekValid) return (*_lastPeek).element() ;
00402 else {
00403 _scv_message::message(_scv_message::BAG_INVALID_PEEK_RETURN,nameP());
00404 return (*_lastPeek).element() ;
00405 }
00406 };
00407
00408 const int count() const { return (*_lastPeek).count() ; }
00409
00410
00411
00412
00413
00414
00415 void add(const T& arg, int num=1) {
00416 if (num > 0) {
00417 _scv_bag_record<T> b(arg, num);
00418 _bag.push_back(b) ;
00419 _size += num;
00420 ++_dsize;
00421 _unmarkedSize += num;
00422 return;
00423 } else {
00424 _scv_message::message(_scv_message::BAG_INVALID_ADD_ARGUMENT,num);
00425 }
00426 }
00427
00428 void push(const T& arg, int num = 1) { add(arg, num); }
00429
00430
00431
00432
00433
00434
00435 const T& peekRandom(bool mark = false) {
00436 if (!_randomP) {
00437 _randomOwner = true;
00438 _randomP = new scv_random(nameP(),_seed);
00439 }
00440 if (_unmarkedSize == 0) {
00441 _scv_message::message(_scv_message::BAG_ZERO_UNMARKED_OBJECTS,"peekRandom");
00442 return (*_bag.end()).element();
00443 }
00444 int i = abs((int)(_randomP->next()) % _unmarkedSize);
00445 _bIterT iter;
00446 for (iter = _bag.begin(); iter != _bag.end(); ++iter) {
00447 if (i < (*iter).uCount()) {
00448 _lastPeek = iter;
00449 _lastPeek.mObjCount() = 0;
00450 _lastPeek.uObjCount() = i + 1;
00451 _lastPeekValid = true;
00452 _lastPeekIsMarked = false ;
00453 _randMode = true;
00454 _rlock = false ;
00455 if (mark) scv_bag::mark();
00456 return (*iter).element();
00457 } else {
00458 i -= (*iter).uCount();
00459 }
00460 }
00461 return (*_bag.end()).element();
00462 }
00463 const T& peek_random(bool mark = false) {
00464 return peekRandom(mark);
00465 }
00466
00467 const T& peekRandom() const {
00468 if (!_randomP) {
00469 _randomOwner = true;
00470 _randomP = new scv_random(nameP(),_seed);
00471 }
00472 if (_unmarkedSize == 0) {
00473 _scv_message::message(_scv_message::BAG_ZERO_UNMARKED_OBJECTS,"peekRandom");
00474 return (*_bag.end()).element();
00475 }
00476 int i = abs((int)(_randomP->next()) % _unmarkedSize);
00477 _bIterT iter;
00478 for (iter = ((scv_bag*) this)->_bag.begin();
00479 iter !=((scv_bag*) this)->_bag.end();
00480 ++iter) {
00481 if (i < (*iter).uCount()) {
00482 _lastPeek = iter;
00483 _lastPeek.mObjCount() = 0;
00484 _lastPeek.uObjCount() = i + 1;
00485 _lastPeekValid = true;
00486 _lastPeekIsMarked = false ;
00487 _randMode = true;
00488 _rlock = false ;
00489 return (*iter).element();
00490 } else {
00491 i -= (*iter).uCount();
00492 }
00493 }
00494 return (*_bag.end()).element();
00495 }
00496
00497 const T& peek_random() const {
00498 return peekRandom();
00499 }
00500
00501 void print (ostream& o=scv_out, int details=0, int indent=0) const;
00502 void show (int details=0, int indent=0) const;
00503
00504 private:
00505
00506
00507 const T& peekNextUnmarked(bool distinct= false) const {
00508 if (_unmarkedSize > 0){
00509
00510
00511 unmarkedPeek(distinct) ;
00512 _lastPeekValid = true;
00513 _lastPeekIsMarked = false ;
00514 _randMode = false;
00515 _rlock = false ;
00516 return (*_lastPeek).element() ;
00517
00518
00519 } else {
00520 _scv_message::message(_scv_message::BAG_ZERO_UNMARKED_OBJECTS,"peakNextUnmarked");
00521 return (*_lastPeek).element() ;
00522 }
00523 }
00524
00525
00526 const T& peekNextMarked(bool distinct = false) const {
00527 if (_unmarkedSize < _size){
00528
00529
00530 markedPeek(distinct) ;
00531 _lastPeekValid = true;
00532 _lastPeekIsMarked = true ;
00533 _randMode = false;
00534 _rlock = false;
00535 return (*_lastPeek).element() ;
00536
00537
00538 } else {
00539 _scv_message::message(_scv_message::BAG_ZERO_MARKED_OBJECTS,"peakNextMarked");
00540 return (*_lastPeek).element() ;
00541 }
00542 }
00543
00544
00545 const T& peekNextAny(bool distinct= false) const {
00546 if (_size >0 ){
00547 nextPeek(distinct);
00548 _lastPeekValid = true;
00549 _lastPeekIsMarked = _lastPeek.mflag();
00550
00551
00552 _randMode = false;
00553 _rlock = false ;
00554 return (*_lastPeek).element();
00555 } else {
00556 _scv_message::message(_scv_message::EMPTY_BAG,nameP());
00557 return (*_lastPeek).element() ;
00558 }
00559 }
00560
00561 public:
00562
00563 const T& peekNext(char peekAt = 'a', bool distinct = false) const {
00564 switch (peekAt) {
00565 case 'u' : return peekNextUnmarked(distinct);
00566 case 'm' : return peekNextMarked(distinct);
00567 default : return peekNextAny(distinct);
00568 }
00569 }
00570 const T& peek_next(char peekAt = 'a', bool distinct = false) const {
00571 return peekNext(peekAt, distinct);
00572 }
00573
00574
00575
00576
00577
00578 void mark(bool AllCopies = false) {
00579 if (_lastPeekValid ) {
00580 if (_lastPeekIsMarked == false || AllCopies) {
00581
00582 int nmark = (*(_lastPeek.modify())).markElement(AllCopies);
00583 _unmarkedSize -= nmark;
00584 _lastPeek.uObjCount() -=nmark;
00585 _lastPeek.mObjCount() +=nmark;
00586 _lastPeekIsMarked = true;
00587 }
00588 } else {
00589 _scv_message::message(_scv_message::BAG_INVALID_PEEK_MARK,nameP());
00590 }
00591 }
00592
00593 void unMark(bool AllCopies = false) {
00594 if (_lastPeekValid) {
00595 if (_lastPeekIsMarked || AllCopies ) {
00596
00597 int nUmark = (*(_lastPeek.modify())).unmarkElement(AllCopies);
00598 _unmarkedSize += nUmark;
00599 _lastPeek.uObjCount() +=nUmark;
00600 _lastPeek.mObjCount() -=nUmark;
00601 _lastPeekIsMarked = false;
00602 }
00603 } else {
00604 _scv_message::message(_scv_message::BAG_INVALID_PEEK_UNMARK,nameP());
00605 }
00606 }
00607 void unmark(bool AllCopies = false) {
00608 unMark(AllCopies);
00609 }
00610
00611
00612
00613
00614
00615 void remove(bool AllCopies = false) {
00616 if (_lastPeekValid && !_rlock) {
00617 (*(_lastPeek.modify())).popCount(_lastPeekIsMarked, AllCopies, _size, _unmarkedSize
00618 , _lastPeek.uObjCount(), _lastPeek.mObjCount());
00619
00620 if ((*_lastPeek).count() == 0) _bagErase();
00621 if (_randMode) _lastPeekValid = false;
00622 _rlock = true ;
00623 return ;
00624 } else {
00625 _scv_message::message(_scv_message::BAG_INVALID_PEEK_ERASE,nameP());
00626 return;
00627 }
00628 }
00629
00630
00631
00632
00633 void clear() {
00634 _bag.clear();
00635 _size = 0;
00636 _dsize = 0 ;
00637 _unmarkedSize = 0;
00638 _lastPeekIsMarked = false ;
00639 _lastPeekValid = false ;
00640 _randMode = true;
00641 return;
00642 }
00643
00644
00645
00646 void unmarkAll() {
00647 _bIterT iter;
00648 for (iter = _bag.begin();
00649 iter != _bag.end();
00650 ++iter) (*iter).unmarkElement(true);
00651 _unmarkedSize = _size;
00652 _lastPeekIsMarked = false ;
00653 }
00654 void unmark_all() {
00655 unmarkAll();
00656 }
00657 void markAll() {
00658 _bIterT iter;
00659 for (iter = _bag.begin();
00660 iter != _bag.end();
00661 ++iter) (*iter).markElement(true);
00662 _unmarkedSize = 0;
00663 _lastPeekIsMarked = true ;
00664 }
00665 void mark_all() {
00666 markAll();
00667 }
00668
00669 bool is_equal(const scv_bag<T>& other) const;
00670
00671 #if defined (_USE_EXPLICIT_NEQ)
00672 bool operator!=(const scv_bag<T>& other);
00673 #endif
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 void read(istream& ) ;
00685
00686 public:
00687 void setRandom(scv_random& random) {
00688 if (_randomOwner) {
00689 delete _randomP;
00690 _randomOwner = false;
00691 }
00692 _randomP = &random;
00693 }
00694 void set_random(scv_random& random) {
00695 setRandom(random);
00696 }
00697 };
00698
00699 template <class T>
00700 void _scv_bag_record<T>::print(ostream& out, int details, int indent) const {
00701
00702 out << " Count: " << count() << " unmarked: " << uCount() << endl;
00703 }
00704
00705 template <class T>
00706 ostream& operator<<(ostream& out, const _scv_bag_record<T>& b) {
00707 b.print(out, 1);
00708 return out;
00709 }
00710
00711
00712
00713
00714
00715 template <class T>
00716 void scv_bag<T>::print(ostream& out, int details, int indent) const {
00717 out << kind() << " Name: " << nameP() << endl;
00718 for( typename list<_scv_bag_record<T> >::const_iterator iter = _bag.begin();
00719 iter != _bag.end();
00720 ++iter) (*iter).print(out,details,indent);
00721 out << endl << endl;
00722 }
00723
00724 template <class T>
00725 void scv_bag<T>::show(int details, int indent) const
00726 {
00727 print(scv_out, details, indent);
00728 }
00729
00730 template <class T>
00731 ostream& operator<<(ostream& out, const scv_bag<T>& t){
00732 t.print(out, 1);
00733 return (out);
00734 }
00735
00736 #if defined (_USE_EXPLICIT_NEQ)
00737 template <class T>
00738 bool scv_bag<T>::operator!=(const scv_bag& other) {
00739 return !(this->_bag == other._bag);
00740 }
00741 #endif
00742
00743 template <class T>
00744 bool scv_bag<T>::is_equal(const scv_bag<T>& other) const {
00745 return (this->_bag == other._bag);
00746 }
00747
00748 template <class T>
00749 bool operator==(const scv_bag<T>& a, const scv_bag<T>& b){
00750 return (a.is_equal(b));
00751 }
00752
00753
00754 template <class T>
00755 void scv_bag<T>::read(istream& in) {
00756
00757 int num = 0; in >> num ;
00758 T ip ;
00759
00760 for (int i = 0 ; i < num ; i++) {
00761 in >> ip ;
00762 this->push(ip);
00763 }
00764
00765 }
00766
00767 template <class T>
00768 istream& operator>>(istream& in, scv_bag<T>& t) {
00769 t.read(in);
00770 return (in);
00771 }
00772
00773
00774 #endif // SCV_BAG_H
00775