00001
00002
00003
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _CHOMP_CUBES_BINCUBE_H_
00039 #define _CHOMP_CUBES_BINCUBE_H_
00040
00041 #include "chomp/system/config.h"
00042 #include "chomp/struct/bitcount.h"
00043 #include "chomp/struct/hashsets.h"
00044
00045 #include <iostream>
00046 #include <fstream>
00047 #include <ctime>
00048 #include <cstdlib>
00049 #include <cstring>
00050 #include <queue>
00051
00052 namespace chomp {
00053 namespace homology {
00054
00055
00056
00057
00058
00059
00062 template <int number, int power>
00063 class Power
00064 {
00065 public:
00066 static const int value = Power<number,power-1>::value * number;
00067 };
00068
00071 template <int number>
00072 class Power<number,0>
00073 {
00074 public:
00075 static const int value = 1;
00076 };
00077
00078
00079
00080
00081
00082
00085 class SetOfFullCubes
00086 {
00087 public:
00091 class OutOfRange
00092 {
00093 };
00094 };
00095
00096
00097
00098
00099
00100
00105 template <int Dim, int twoPower>
00106 class FixDimBitmap
00107 {
00108 public:
00109 protected:
00110 };
00111
00112
00113
00114
00115
00116
00119 template <int Dim, int twoPower>
00120 class bincube: public FixDimBitmap<Dim,twoPower>, public SetOfFullCubes
00121 {
00122 public:
00124 bincube ();
00125
00128 bincube (char *buffer);
00129
00131 bincube (const bincube<Dim,twoPower> &b);
00132
00134 bincube<Dim,twoPower> &operator = (const bincube<Dim,twoPower> &b);
00135
00137 ~bincube ();
00138
00140 static int dimension ();
00141 static const int MaxDim;
00142
00146 int findcube (int start = 0) const;
00147
00149 class iterator
00150 {
00151 friend class bincube<Dim,twoPower>;
00152 public:
00154 typedef int CoordType;
00155
00157 iterator (bincube<Dim,twoPower> *bcub = 0, int num = -1);
00158
00161 iterator &operator ++ ();
00162
00164 iterator &operator ++ (int);
00165
00167 operator int () const;
00168
00170 static const int MaxDim;
00171
00173 static int dim ();
00174
00176 const int *coord () const;
00177
00179 template <class intType>
00180 intType *coord (intType *tab) const;
00181
00182
00184 bincube<Dim,twoPower> *b;
00185
00187 int n;
00188
00189 };
00190
00192 iterator begin ();
00193
00195 iterator end ();
00196
00198 static const int max_neighbors;
00199
00201 class neighborhood_iterator: public iterator
00202 {
00203 public:
00205 neighborhood_iterator (bincube<Dim,twoPower> *bcub = 0,
00206 int n = -1, int inicur = -1);
00207
00210 neighborhood_iterator &operator ++ ();
00211
00213 neighborhood_iterator &operator ++ (int);
00214
00216 operator int () const;
00217
00219
00220
00222
00223
00224
00225
00226 protected:
00228 bincube<Dim,twoPower> *b;
00229
00231 int coord [Dim];
00232
00234 int ncoord [Dim];
00235
00237 int curnum;
00238
00240 int cur;
00241
00242 };
00243
00246 neighborhood_iterator neighborhood_begin (int number) const;
00247
00249 neighborhood_iterator neighborhood_end (int number) const;
00250
00253 void add (int number);
00254
00257 template <class intType>
00258 void add (const intType *coord);
00259
00262 bool check (int number) const;
00263
00266 template <class intType>
00267 bool check (const intType *coord) const;
00268
00271 void remove (int number);
00272
00275 template <class intType>
00276 void remove (const intType *coord);
00277
00279 const char *getbuffer () const;
00280
00282 operator const char * () const;
00283
00285 static int getbufsize ();
00286
00288 std::istream &read (std::istream &in);
00289
00291 static bool wrapped (int dir);
00292
00294 static void wrap (int dir);
00295
00297 static void dontwrap (int dir);
00298
00300 template <class intType>
00301 static intType wrap (intType coord, int dir);
00302
00305 template <class intType>
00306 static int coord2num (const intType *coord);
00307
00309 template <class intType>
00310 static intType *num2coord (int number, intType *coord);
00311
00315 template <class intType>
00316 static const intType *num2coord (int number);
00317
00319 int count () const;
00320 operator int () const;
00321
00323 bool empty () const;
00324
00326 void clear ();
00327
00329 static const int maxcount;
00330
00331 protected:
00333 char *buf;
00334
00336 bool allocated;
00337
00339 mutable int cardinality;
00340
00342 static const int bufsize;
00343
00345 static const int twoMask;
00346
00348 static const int width;
00349
00351 static int wrapping;
00352
00353 };
00354
00355 template <int Dim, int twoPower>
00356 const int bincube<Dim,twoPower>::bufsize = 1 << (Dim * twoPower - 3);
00357
00358 template <int Dim, int twoPower>
00359 const int bincube<Dim,twoPower>::maxcount = 1 << (Dim * twoPower);
00360
00361 template <int Dim, int twoPower>
00362 const int bincube<Dim,twoPower>::twoMask = ~0u >> (32 - twoPower);
00363
00364 template <int Dim, int twoPower>
00365 const int bincube<Dim,twoPower>::width = 1 << twoPower;
00366
00367 template <int Dim, int twoPower>
00368 int bincube<Dim,twoPower>::wrapping = 0;
00369
00370 template <int Dim, int twoPower>
00371 const int bincube<Dim,twoPower>::MaxDim = Dim;
00372
00373 template <int Dim, int twoPower>
00374 const int bincube<Dim,twoPower>::iterator::MaxDim = Dim;
00375
00376 template <int Dim, int twoPower>
00377 const int bincube<Dim,twoPower>::max_neighbors = Power<3,Dim>::value - 1;
00378
00379
00380
00381
00382 template <int Dim, int twoPower>
00383 inline bincube<Dim,twoPower>::bincube ()
00384 {
00385 buf = new char [bufsize];
00386 allocated = true;
00387 memset (buf, 0, bufsize);
00388 cardinality = 0;
00389 return;
00390 }
00391
00392 template <int Dim, int twoPower>
00393 inline bincube<Dim,twoPower>::bincube (char *buffer)
00394 {
00395 buf = buffer;
00396 allocated = false;
00397 cardinality = -1;
00398 return;
00399 }
00400
00401 template <int Dim, int twoPower>
00402 inline bincube<Dim,twoPower>::bincube (const bincube<Dim,twoPower> &b)
00403 {
00404 buf = new char [bufsize];
00405 allocated = true;
00406 memcpy (buf, b. buf, bufsize);
00407 cardinality = b. cardinality;
00408 return;
00409 }
00410
00411 template <int Dim, int twoPower>
00412 inline bincube<Dim,twoPower> &
00413 bincube<Dim,twoPower>::operator = (const bincube<Dim,twoPower> &b)
00414 {
00415 memcpy (buf, b. buf, bufsize);
00416 cardinality = b. cardinality;
00417 return;
00418 }
00419
00420 template <int Dim, int twoPower>
00421 inline bincube<Dim,twoPower>::~bincube ()
00422 {
00423 if (allocated)
00424 delete [] buf;
00425 return;
00426 }
00427
00428
00429
00430 template <int Dim, int twoPower>
00431 inline int bincube<Dim,twoPower>::dimension ()
00432 {
00433 return Dim;
00434 }
00435
00436 template <int Dim, int twoPower>
00437 inline bool bincube<Dim,twoPower>::wrapped (int dir)
00438 {
00439 return bincube<Dim,twoPower>::wrapping & (1 << dir);
00440 }
00441
00442 template <int Dim, int twoPower>
00443 inline void bincube<Dim,twoPower>::wrap (int dir)
00444 {
00445 bincube<Dim,twoPower>::wrapping |= (1 << dir);
00446 return;
00447 }
00448
00449 template <int Dim, int twoPower>
00450 inline void bincube<Dim,twoPower>::dontwrap (int dir)
00451 {
00452 bincube<Dim,twoPower>::wrapping &= ~(1 << dir);
00453 return;
00454 }
00455
00456 template <int Dim, int twoPower>
00457 template <class intType>
00458 inline intType bincube<Dim,twoPower>::wrap (intType coord, int dir)
00459 {
00460 if (wrapped (dir))
00461 {
00462
00463
00464 while (coord < 0)
00465 coord += width;
00466 while (coord >= width)
00467 coord -= width;
00468 }
00469 return coord;
00470 }
00471
00472
00473
00474 template <int Dim, int twoPower>
00475 template <class intType>
00476 inline int bincube<Dim,twoPower>::coord2num (const intType *coord)
00477 {
00478 int number = 0;
00479 for (int i = Dim - 1; i >= 0; -- i)
00480 {
00481 int c = coord [i];
00482 if (wrapped (i))
00483 {
00484
00485
00486 while (c < 0)
00487 c += width;
00488 while (c >= width)
00489 c -= width;
00490 }
00491 else if ((c < 0) || (c >= width))
00492 throw SetOfFullCubes::OutOfRange ();
00493 number <<= twoPower;
00494 number |= c;
00495 }
00496 return number;
00497 }
00498
00499 template <int Dim, int twoPower>
00500 template <class intType>
00501 inline intType *bincube<Dim,twoPower>::num2coord (int number, intType *coord)
00502 {
00503 for (int i = 0; i < Dim; ++ i)
00504 {
00505 coord [i] = number & bincube<Dim,twoPower>::twoMask;
00506 number >>= twoPower;
00507 }
00508 return coord;
00509 }
00510
00511 template <int Dim, int twoPower>
00512 template <class intType>
00513 inline const intType *bincube<Dim,twoPower>::num2coord (int )
00514 {
00515 return 0;
00516 }
00517
00518
00519
00520 template <int Dim, int twoPower>
00521 inline int bincube<Dim,twoPower>::findcube (int start) const
00522 {
00523
00524 int offset = start >> 3;
00525
00526
00527 if (offset >= bufsize)
00528 return maxcount;
00529
00530
00531 if (buf [offset])
00532 {
00533 int bitnumber = start & 7;
00534 while (bitnumber < 8)
00535 {
00536 if (buf [offset] & (1 << bitnumber))
00537 return (offset << 3) + bitnumber;
00538 ++ bitnumber;
00539 }
00540 }
00541
00542
00543 while (1)
00544 {
00545 ++ offset;
00546 if (offset >= bufsize)
00547 return maxcount;
00548 if (buf [offset])
00549 break;
00550 }
00551
00552
00553 int bitnumber = 0;
00554 while (1)
00555 {
00556 if (buf [offset] & (1 << bitnumber))
00557 return (offset << 3) + bitnumber;
00558 ++ bitnumber;
00559 }
00560 }
00561
00562
00563
00564 template <int Dim, int twoPower>
00565 inline bool bincube<Dim,twoPower>::check (int number) const
00566 {
00567 return buf [number >> 3] & (1 << (number & 7));
00568 }
00569
00570 template <int Dim, int twoPower>
00571 template <class intType>
00572 inline bool bincube<Dim,twoPower>::check (const intType *coord) const
00573 {
00574 return check (coord2num (coord));
00575 }
00576
00577 template <int Dim, int twoPower>
00578 inline void bincube<Dim,twoPower>::add (int number)
00579 {
00580 if ((cardinality >= 0) && !check (number))
00581 ++ cardinality;
00582 buf [number >> 3] |= (char) (1 << (number & 7));
00583 return;
00584 }
00585
00586 template <int Dim, int twoPower>
00587 template <class intType>
00588 inline void bincube<Dim,twoPower>::add (const intType *coord)
00589 {
00590 return add (coord2num (coord));
00591 }
00592
00593 template <int Dim, int twoPower>
00594 inline void bincube<Dim,twoPower>::remove (int number)
00595 {
00596 if ((cardinality > 0) && check (number))
00597 -- cardinality;
00598 buf [number >> 3] &= (char) (~(1 << (number & 7)));
00599 return;
00600 }
00601
00602 template <int Dim, int twoPower>
00603 template <class intType>
00604 inline void bincube<Dim,twoPower>::remove (const intType *coord)
00605 {
00606 return remove (coord2num (coord));
00607 }
00608
00609
00610
00611 template <int Dim, int twoPower>
00612 inline bincube<Dim,twoPower>::iterator::iterator
00613 (bincube<Dim,twoPower> *bcub, int num): b (bcub), n (num)
00614 {
00615 return;
00616 }
00617
00618 template <int Dim, int twoPower>
00619 inline typename bincube<Dim,twoPower>::iterator &
00620 bincube<Dim,twoPower>::iterator::operator ++ ()
00621 {
00622 if (!b || (n >= bincube<Dim,twoPower>::maxcount))
00623 return *this;
00624 n = b -> findcube (n + 1);
00625 return *this;
00626 }
00627
00628 template <int Dim, int twoPower>
00629 inline typename bincube<Dim,twoPower>::iterator &
00630 bincube<Dim,twoPower>::iterator::operator ++ (int)
00631 {
00632 iterator prev = *this;
00633 ++ *this;
00634 return prev;
00635 }
00636
00637 template <int Dim, int twoPower>
00638 inline bincube<Dim,twoPower>::iterator::operator int () const
00639 {
00640 return n;
00641 }
00642
00643 template <int Dim, int twoPower>
00644 inline int bincube<Dim,twoPower>::iterator::dim ()
00645 {
00646 return Dim;
00647 }
00648
00649 template <int Dim, int twoPower>
00650 inline const int *bincube<Dim,twoPower>::iterator::coord () const
00651 {
00652 return 0;
00653 }
00654
00655 template <int Dim, int twoPower>
00656 template <class intType>
00657 inline intType *bincube<Dim,twoPower>::iterator::coord (intType *tab) const
00658 {
00659 return bincube<Dim,twoPower>::num2coord (n, tab);
00660 }
00661
00662
00663
00664 template <class coordinate>
00665 inline void bit2neighborAlg (int number, const coordinate *src,
00666 coordinate *dest, int Dim)
00667 {
00668 ++ number;
00669 for (int i = Dim - 1; i >= 0; -- i)
00670 {
00671 dest [i] = src [i];
00672 switch (number % 3)
00673 {
00674 case 2:
00675 -- (dest [i]);
00676 break;
00677 case 1:
00678 ++ (dest [i]);
00679 break;
00680 case 0:
00681 break;
00682 default:
00683 throw "Erratic neighbor.";
00684 }
00685 number /= 3;
00686 }
00687
00688 return;
00689 }
00690
00691 template <class settype>
00692 typename settype::iterator bit2neighborAlg
00693 (const typename settype::iterator &q, int n)
00694 {
00695 const int Dim = settype::MaxDim;
00696 int coord [Dim];
00697 q. b -> num2coord (q, coord);
00698 bit2neighborAlg (n, coord, coord, Dim);
00699 try
00700 {
00701 return typename settype::iterator (q. b,
00702 q. b -> coord2num (coord));
00703 }
00704 catch (...)
00705 {
00706 }
00707 return q;
00708 }
00709
00710
00711
00712 template <int Dim, int twoPower>
00713 inline bincube<Dim,twoPower>::neighborhood_iterator::neighborhood_iterator
00714 (bincube<Dim,twoPower> *bcub, int num, int inicur):
00715 b (bcub), curnum (-1), cur (inicur)
00716 {
00717 if (b && (num >= 0))
00718 b -> num2coord (num, coord);
00719 if (num == bincube<Dim,twoPower>::max_neighbors)
00720 {
00721 for (int i = 0; i < Dim; ++ i)
00722 ncoord [i] = 0;
00723 }
00724 return;
00725 }
00726
00727 template <int Dim, int twoPower>
00728 inline typename bincube<Dim,twoPower>::neighborhood_iterator &
00729 bincube<Dim,twoPower>::neighborhood_iterator::operator ++ ()
00730 {
00731 if (!b || (cur >= bincube<Dim,twoPower>::max_neighbors))
00732 return *this;
00733 while (1)
00734 {
00735 ++ cur;
00736 if (cur >= bincube<Dim,twoPower>::max_neighbors)
00737 {
00738 for (int i = 0; i < Dim; ++ i)
00739 ncoord [i] = 0;
00740 curnum = -1;
00741 return *this;
00742 }
00743 bit2neighborAlg (cur, coord, ncoord, Dim);
00744 try
00745 {
00746 curnum = b -> coord2num (ncoord);
00747 if (b -> check (curnum))
00748 return *this;
00749 }
00750 catch (...)
00751 {
00752 }
00753 }
00754 return *this;
00755 }
00756
00757 template <int Dim, int twoPower>
00758 inline typename bincube<Dim,twoPower>::neighborhood_iterator &
00759 bincube<Dim,twoPower>::neighborhood_iterator::operator ++ (int)
00760 {
00761 if (!b || (cur >= bincube<Dim,twoPower>::maxcount))
00762 return *this;
00763 neighborhood_iterator prev = *this;
00764 ++ (*this);
00765 return prev;
00766 }
00767
00768 template <int Dim, int twoPower>
00769 inline bincube<Dim,twoPower>::neighborhood_iterator::operator int () const
00770 {
00771 return curnum;
00772 }
00773
00774 template <int Dim, int twoPower>
00775 inline bool operator ==
00776 (const typename bincube<Dim,twoPower>::neighborhood_iterator &x1,
00777 const typename bincube<Dim,twoPower>::neighborhood_iterator &x2)
00778 {
00779
00780 return ((x1. b == x2. b) && (x1. cur == x2. cur));
00781 }
00782
00783 template <int Dim, int twoPower>
00784 inline bool operator !=
00785 (const typename bincube<Dim,twoPower>::neighborhood_iterator &x1,
00786 const typename bincube<Dim,twoPower>::neighborhood_iterator &x2)
00787 {
00788
00789 return !(x1 == x2);
00790 }
00791
00792
00793
00794 template <int Dim, int twoPower>
00795 inline typename bincube<Dim,twoPower>::neighborhood_iterator
00796 bincube<Dim,twoPower>::neighborhood_begin (int n) const
00797 {
00798 typename bincube<Dim,twoPower>::neighborhood_iterator iter
00799 (const_cast<bincube<Dim,twoPower> *> (this), n);
00800 return ++ iter;
00801 }
00802
00803 template <int Dim, int twoPower>
00804 inline typename bincube<Dim,twoPower>::neighborhood_iterator
00805 bincube<Dim,twoPower>::neighborhood_end (int n) const
00806 {
00807 return neighborhood_iterator
00808 (const_cast<bincube<Dim,twoPower> *> (this), n,
00809 max_neighbors);
00810 }
00811
00812
00813
00814 template <int Dim, int twoPower>
00815 inline typename bincube<Dim,twoPower>::iterator
00816 bincube<Dim,twoPower>::begin ()
00817 {
00818 return iterator (this, findcube ());
00819 }
00820
00821 template <int Dim, int twoPower>
00822 inline typename bincube<Dim,twoPower>::iterator
00823 bincube<Dim,twoPower>::end ()
00824 {
00825 return iterator (this, maxcount);
00826 }
00827
00828
00829
00830 template <int Dim, int twoPower>
00831 inline const char *bincube<Dim,twoPower>::getbuffer () const
00832 {
00833 return buf;
00834 }
00835
00836 template <int Dim, int twoPower>
00837 inline bincube<Dim,twoPower>::operator const char * () const
00838 {
00839 return buf;
00840 }
00841
00842 template <int Dim, int twoPower>
00843 inline int bincube<Dim,twoPower>::getbufsize ()
00844 {
00845 return bufsize;
00846 }
00847
00848 template <int Dim, int twoPower>
00849 inline std::istream &bincube<Dim,twoPower>::read (std::istream &in)
00850 {
00851 in. read (buf, bufsize);
00852 cardinality = -1;
00853 return in;
00854 }
00855
00856
00857
00858 template <int Dim, int twoPower>
00859 inline int bincube<Dim,twoPower>::count () const
00860 {
00861 if (cardinality >= 0)
00862 return cardinality;
00863 char *byte = buf;
00864 char *end = byte + bufsize;
00865 int c = 0;
00866 while (byte != end)
00867 {
00868 c += bitcountbyte (*byte);
00869 ++ byte;
00870 }
00871 cardinality = c;
00872 return cardinality;
00873 }
00874
00875 template <int Dim, int twoPower>
00876 inline bincube<Dim,twoPower>::operator int () const
00877 {
00878 return count ();
00879 }
00880
00881 template <int Dim, int twoPower>
00882 inline bool bincube<Dim,twoPower>::empty () const
00883 {
00884 return !count ();
00885 }
00886
00887 template <int Dim, int twoPower>
00888 inline void bincube<Dim,twoPower>::clear ()
00889 {
00890 memset (buf, 0, bufsize);
00891 cardinality = 0;
00892 return;
00893 }
00894
00895
00896
00897 template <int Dim, int twoPower>
00898 inline std::ostream &operator << (std::ostream &out,
00899 const bincube<Dim,twoPower> & b)
00900 {
00901 return out. write (static_cast<const char *> (b), b. getbufsize ());
00902 }
00903
00904 template <int Dim, int twoPower>
00905 inline std::istream &operator >> (std::istream &in,
00906 bincube<Dim,twoPower> & b)
00907 {
00908 return b. read (in);
00909 }
00910
00911
00912
00916 template <class cubetype, class settype>
00917 class NeighborsBdd
00918 {
00919 public:
00920
00921 NeighborsBdd (const cubetype &middle, const settype &cset):
00922 q (middle), s (cset) {};
00923
00924
00925
00926
00927 bool check (int n) const
00928 {
00929 cubetype neighbor = bit2neighborAlg<settype> (q, n);
00930 if (neighbor == q)
00931 return false;
00932 return (s. check (neighbor));
00933 }
00934
00935 private:
00936
00937 const cubetype &q;
00938
00939
00940 const settype &s;
00941
00942 };
00943
00946 template <class SetT>
00947 class Acyclic1d
00948 {
00949 public:
00950 static bool check (typename SetT::iterator q, const SetT &s)
00951 {
00952 NeighborsBdd<typename SetT::iterator,SetT> n (q, s);
00953 return acyclic1d (n);
00954 }
00955 static bool check (int n, const SetT &s)
00956 {
00957
00958 typename SetT::iterator q (const_cast<SetT *> (&s), n);
00959 return check (q, s);
00960 }
00961 };
00962
00965 template <class SetT>
00966 class Acyclic2d
00967 {
00968 public:
00969 static bool check (typename SetT::iterator q, const SetT &s)
00970 {
00971 NeighborsBdd<typename SetT::iterator,SetT> n (q, s);
00972 return acyclic2d (n);
00973 }
00974 static bool check (int n, const SetT &s)
00975 {
00976
00977 typename SetT::iterator q (const_cast<SetT *> (&s), n);
00978 return check (q, s);
00979 }
00980 };
00981
00984 template <class SetT>
00985 class Acyclic3d
00986 {
00987 public:
00988 static bool check (typename SetT::iterator q, const SetT &s)
00989 {
00990 NeighborsBdd<typename SetT::iterator,SetT> n (q, s);
00991 return acyclic3d (n);
00992 }
00993 static bool check (int n, const SetT &s)
00994 {
00995
00996 typename SetT::iterator q (const_cast<SetT *> (&s), n);
00997 return check (q, s);
00998 }
00999 };
01000
01001
01002
01004 template <class Number>
01005 class hashNumber
01006 {
01007 public:
01009 hashNumber (Number n = 0): number (n) {return;}
01010
01012 operator Number () const {return number;}
01013
01014 protected:
01015 int number;
01016 };
01017
01019 template <class Number>
01020 inline int_t hashkey1 (const hashNumber<Number> &n)
01021 {
01022 return static_cast<int_t> (static_cast<Number> (n));
01023 }
01024
01026 template <class Number>
01027 inline int_t hashkey2 (const hashNumber<Number> &n)
01028 {
01029 return static_cast<int_t> (static_cast<Number> (n) ^
01030 0xFA5A75A7ul) << 5;
01031 }
01032
01033 typedef hashedset<hashNumber<int> > hashIntQueue;
01034
01035
01036
01038 template <class SetT, class QueueT>
01039 void addneighbors (const int &c, const SetT &s, QueueT &q)
01040 {
01041 typename SetT::neighborhood_iterator cur = s. neighborhood_begin (c),
01042 end = s. neighborhood_end (c);
01043 while (cur != end)
01044 {
01045 q. add (hashNumber<int> (cur));
01046 ++ cur;
01047 }
01048 return;
01049 }
01050
01055 template <typename SetT, typename Acyclic, typename QueueT>
01056 int reduceFullCubesAlg (SetT &X, bool quiet)
01057 {
01058
01059 QueueT Q;
01060
01061
01062 int count = 0;
01063 bool exitloop = false;
01064 bool lastrun = false;
01065 while (!exitloop)
01066 {
01067
01068 if (lastrun)
01069 exitloop = true;
01070
01071 int countremoved = 0, countleft = 0;
01072 typename SetT::iterator cur = X. begin (), end = X. end ();
01073 while (cur != end)
01074 {
01075 if (Acyclic::check (cur, X))
01076 {
01077 X. remove (cur);
01078 ++ countremoved;
01079 if (lastrun)
01080 addneighbors (cur, X, Q);
01081 }
01082 else
01083 ++ countleft;
01084 ++ cur;
01085
01086
01087 if (!quiet && !(count % 5273))
01088 scon << std::setw (10) << count <<
01089 "\b\b\b\b\b\b\b\b\b\b";
01090 ++ count;
01091 }
01092 if (!quiet)
01093 sout << ".";
01094
01095 if (!lastrun && (countremoved - 10 < (countleft >> 2)))
01096 lastrun = true;
01097 }
01098
01099 if (!quiet)
01100 sout << " ";
01101 count = 0;
01102 while (!Q. empty ())
01103 {
01104 typename QueueT::value_type elem = Q. front ();
01105 Q. pop ();
01106 if (Acyclic::check (elem, X))
01107 {
01108 X. remove (elem);
01109 addneighbors (elem, X, Q);
01110 }
01111
01112
01113 if (!quiet && !(count % 5273))
01114 scon << std::setw (10) << count <<
01115 "\b\b\b\b\b\b\b\b\b\b";
01116 count ++;
01117 }
01118
01119 return 0;
01120 }
01121
01122
01124
01125
01126
01127
01128
01129
01130
01132
01133
01134
01135
01136
01137
01138
01140
01141
01142
01143
01144
01145
01146
01148
01149
01150
01151
01152
01153
01154
01155
01157 template <class FullCubSet>
01158 inline int reduceFullCubes (FullCubSet &X, bool quiet = false)
01159 {
01160 switch (X. dimension ())
01161 {
01162 case 3:
01163 return reduceFullCubesAlg<FullCubSet,
01164 Acyclic3d<FullCubSet>,hashIntQueue> (X, quiet);
01165 case 2:
01166 return reduceFullCubesAlg<FullCubSet,
01167 Acyclic2d<FullCubSet>,hashIntQueue> (X, quiet);
01168 case 1:
01169 return reduceFullCubesAlg<FullCubSet,
01170 Acyclic1d<FullCubSet>,hashIntQueue> (X, quiet);
01171 default:
01172 throw "Binary cube reduction not implemented "
01173 "for dimension > 3.";
01174 }
01175 }
01176
01177
01178 }
01179 }
01180
01181 #endif // _CHOMP_CUBES_BINCUBE_H_
01182
01184