Advertisement
Guest User

enumeration of antimatroid, bforce + symmetries + parallel

a guest
Apr 18th, 2013
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.68 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <mutex>
  6. #include <thread>
  7.  
  8. using namespace std;
  9.  
  10. typedef unsigned long long ull;
  11. typedef unsigned int us;
  12.  
  13.  
  14. int n = 7;
  15. const int N = 1<<n;
  16. const ull all = -1;
  17. const int thread_cnt = 8;
  18.  
  19. const int factorial[] = {1,1,2,6,24,120,720,5040};
  20.  
  21.  
  22. class u128
  23. {
  24.     public:
  25.         ull low;
  26.         ull high;
  27.         u128(ull _low=0, ull _high = 0)
  28.         {
  29.             low = _low;
  30.             high = _high;
  31.         }
  32.  
  33.         bool operator<(const u128& b) const
  34.         {
  35.             return (high==b.high) ? (low<b.low) : (high<b.high);
  36.         }
  37.  
  38.         bool operator==(const u128& b) const
  39.         {
  40.             return (high==b.high) && (low==b.low);
  41.         }
  42.  
  43.         u128 operator~() const
  44.         {
  45.             return u128(~low,~high);
  46.         }
  47.  
  48.         u128 operator&(const u128& b) const
  49.         {
  50.             return u128(low&b.low, high&b.high);
  51.         }
  52.  
  53.         u128 operator|=(const u128& b)
  54.         {
  55.             low |= b.low;
  56.             high |= b.high;
  57.             return *this;
  58.         }
  59.         u128 operator&=(const u128& b)
  60.         {
  61.             low &= b.low;
  62.             high &= b.high;
  63.             return *this;
  64.         }
  65.  
  66.         void setbit(unsigned i)
  67.         {
  68.             if(i<64)
  69.                 low |= (1ull << i);
  70.             else
  71.                 high |= (1ull << (i-64));
  72.         }
  73.  
  74.         void erasebit(unsigned i)
  75.         {
  76.             if(i<64)
  77.                 low &= ~(1ull << i);
  78.             else
  79.                 high &= ~(1ull << (i-64));
  80.         }
  81.  
  82.         bool getbit(unsigned i) const
  83.         {
  84.             return (i<64) ? (low & (1ull << i)) : (high & (1ull << (i-64)));
  85.         }
  86.  
  87.         void scan()
  88.         {
  89.             cin >> low >> high;
  90.         }
  91.  
  92.         void print() const
  93.         {
  94.             cout << low << ' ' << high << endl;
  95.         }
  96.  
  97. };
  98.  
  99. const int magic = 2000003;
  100. int hash_(const u128& X)
  101. {
  102.     int ret = (X.low%magic)+(X.high%magic);
  103.     return ret<magic?ret:ret-magic;
  104. }
  105. class hashtable
  106. {
  107.     public:
  108.         vector<vector<u128> > table;
  109.         int size;
  110.         mutex mtx_;
  111.         hashtable()
  112.         {
  113.             table.resize(magic);
  114.             size = 0;
  115.         }
  116.         void insert(const u128& X)
  117.         {
  118.             int h = hash_(X);
  119.             bool ok = true;
  120.             mtx_.lock();
  121.             for(auto& i : table[h])
  122.                 if(i==X)
  123.                 {
  124.                     ok = false;
  125.                     break;
  126.                 }
  127.             if(ok)
  128.             {
  129.                 table[h].push_back(X);
  130.                 size++;
  131.             }
  132.             mtx_.unlock();
  133.         }
  134. };
  135.  
  136. class producer
  137. {
  138.     mutex mtx_;
  139.     public:
  140.     int s;
  141.     bool get(u128& x)
  142.     {
  143.         lock_guard<mutex> guard(mtx_);
  144.         if(s==0)
  145.             return false;
  146.         s--;
  147.         x.scan();
  148.         return true;
  149.     }
  150. };
  151.  
  152. vector<vector<int> > perms;
  153. int psize;
  154. vector<vector<int> > ap;
  155. vector<u128> pred;
  156. vector<u128> succ;
  157.  
  158. int apply(vector<int> p, int x)
  159. {
  160.     int y = 0;
  161.     for(int i=0;i<n;i++)
  162.         if(x & (1<<i))
  163.             y |= 1<<p[i];
  164.     return y;
  165. }
  166.  
  167. pair<u128,vector<int> > _reduce(const u128& X)
  168. {
  169.     u128 R;
  170.     vector<int> C = {0};
  171.     vector<int> nC;
  172.     C.reserve(psize);
  173.     nC.reserve(psize);
  174.     R.setbit(0);
  175.     int i=1;
  176.     for(int bit=0;bit<n;bit++)
  177.     {
  178.         int ss = C.size();
  179.         C.resize(ss*(n-bit));
  180.         for(int it=ss;it<ss*(n-bit);it++)
  181.             C[it] = C[it-ss]+factorial[n-1-bit];
  182.         for(;i<(1<<(bit+1));i++)
  183.         {
  184.             nC.clear();
  185.             bool v = false;
  186.             for(auto& t : C)
  187.             {
  188.                 bool nv = X.getbit(ap[i][t]);
  189.                 if(nv > v)
  190.                 {
  191.                     nC.clear();
  192.                     v = nv;
  193.                     R.setbit(i);
  194.                 }
  195.                 if(nv == v)
  196.                 {
  197.                     nC.push_back(t);
  198.                 }
  199.             }
  200.             swap(nC,C);
  201.         }
  202.     }
  203.     return make_pair(R,C);
  204. }
  205. u128 reduce(const u128& X)
  206. {
  207.     return _reduce(X).first;
  208. }
  209. vector<int> aut(const u128& X)
  210. {
  211.     return _reduce(X).second;
  212. }
  213.  
  214. producer P;
  215. hashtable nL;
  216.  
  217. class counter
  218. {
  219.     mutex mtx_;
  220.     public:
  221.         long long cnt;
  222.         void inc(long long x)
  223.         {
  224.             mtx_.lock();
  225.             cnt += x;
  226.             mtx_.unlock();
  227.         }
  228.  
  229. };
  230.  
  231. counter ans;
  232.  
  233. void consumer()            
  234. {
  235.     u128 S;
  236.     while(P.get(S))
  237.     {
  238.         vector<int> automorph = aut(S);
  239.         ans.inc(psize/automorph.size());
  240.         u128 mask(0,0);
  241.         for(int I=1;I<N-1;I++)
  242.             if(S.getbit(I))
  243.                 for(int J=1;J<I;J++)
  244.                     if(S.getbit(J))
  245.                     {
  246.                         int IJ = I|J;
  247.                         if(IJ != I && IJ != J)
  248.                             mask.setbit(IJ);
  249.                     }
  250.  
  251.  
  252.         mask = S & ~mask;
  253.         u128 f1,f2;
  254.         for(int I=0;I<N;I++)
  255.             if(S.getbit(I))
  256.             {
  257.                 f2 |= succ[I] & f1;
  258.                 f1 |= succ[I];
  259.             }
  260.         f1 &= ~f2 & S;
  261.         for(int I=0;I<N;I++)
  262.             if(f1.getbit(I))
  263.                 mask = mask & ~pred[I];
  264.  
  265.         for(int I=1;I<N-1;I++)
  266.             if(mask.getbit(I))
  267.             {
  268.                 for(int a=0;a<automorph.size();a++)
  269.                     mask.erasebit(ap[I][automorph[a]]);
  270.                 u128 nS = S;
  271.                 nS.erasebit(I);
  272.                 nL.insert(reduce(nS));
  273.             }
  274.     }
  275. }
  276.  
  277.  
  278. int main()
  279. {
  280.     pred.resize(N);
  281.     succ.resize(N);
  282.     for(int I=0;I<N;I++)
  283.         for(int i=0;i<n;i++)
  284.             if(I & (1<<i))
  285.                 pred[I].setbit(I & ~(1<<i));
  286.             else
  287.                 succ[I].setbit(I | (1<<i));
  288.     vector<int> start;
  289.     for(int i=0;i<n;i++)
  290.         start.push_back(i);
  291.     do
  292.     {
  293.         perms.push_back(start);
  294.     }
  295.     while(next_permutation(start.begin(),start.end()));
  296.     psize = perms.size();
  297.     ap.resize(N, vector<int>(psize));
  298.  
  299.     for(int p=0;p<psize;p++)
  300.         for(int i=0;i<N;i++)
  301.             ap[i][p] = apply(perms[p], i);
  302.  
  303.     int bc = N;
  304.     cin >> bc >> ans.cnt >> P.s;
  305.  
  306.     cerr << bc << " : " << P.s << endl;
  307.     bc--;
  308.  
  309.     vector<thread> threads;
  310.     for(int i=0;i<thread_cnt;i++)
  311.       threads.emplace_back(consumer);
  312.     for (auto& t: threads) t.join();
  313.    
  314.     cerr << bc << " : " << nL.size << endl;
  315.     cout << bc << ' ' << ans.cnt << endl;
  316.     cout << nL.size << endl;
  317.     for(int ii=0;ii<magic;ii++)
  318.         for(auto& it : nL.table[ii])
  319.             it.print();
  320. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement