Advertisement
Guest User

Untitled

a guest
Jun 18th, 2021
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.59 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct pardes{ // parallel design
  5.         int q,k,r,cost; // q is the number of blocks per class, k is the block size and r is the number of classes
  6.         vector < vector<int> > classes; // each vector stores the "permutation" for a paralel class
  7.         vector < vector<int> > a; // matrix of satisfied pairs
  8.         pardes(int qp,int kp,int rp){ // this just sets up the size of the "classes" vectors
  9.                 // in which each class is the same "continuous" blocks
  10.                 q = qp;
  11.                 k = kp;
  12.                 r = rp;
  13.                 vector <int> v (q*k);
  14.                 for(int i=0;i<q*k;i++){
  15.                         v[i] = i;
  16.                 }
  17.                 for(int i=0;i<r;i++){
  18.                         classes.push_back(v);
  19.                 }
  20.         }
  21.         void builda(){ // builds the a matrix from scratch
  22.                 a = vector < vector <int> >  (q*k, vector <int> (q*k) ); // matrix of fullfiled pairs;
  23.                 for(int i=0;i<r;i++){
  24.                         for(int j=0;j<q;j++){
  25.                                 for(int p1=0;p1<k;p1++){
  26.                                         for(int p2=0;p2<k;p2++){
  27.                                                 if( p1 == p2) continue;
  28.                                                 a[classes[i][j*k+p1]][classes[i][j*k+p2]] ++;
  29.                                         }
  30.                                 }
  31.                         }
  32.                 }
  33.  
  34.         }
  35.         void setcost(){
  36.                 // the number of uncovered pairs, as described in the article
  37.                 // this assumes a has been built and is correct
  38.                 cost = 0;
  39.                 for(int i=0;i<k*q;i++){
  40.                         for(int j=i+1;j<k*q;j++){
  41.                                 if( a[i][j] == 0) cost ++;
  42.                         }
  43.                 }
  44.         }
  45.         void  modify( int i,int j,int d){
  46.                 int old = a[i][j];
  47.                 a[i][j] += d;
  48.                 if( i<j && old == 0 && a[i][j] != 0 ) cost--;
  49.                 if( i<j && old != 0 && a[i][j] == 0) cost ++;
  50.         }
  51.         void transpose(int i,int p1,int p2){
  52.                 // this cheaply transposes two positions while keeping all the stuff correct
  53.                 int b1 = p1/k;
  54.                 int b2 = p2/k;
  55.                 int v1 = classes[i][p1];
  56.                 int v2 = classes[i][p2];
  57.                 p1 = p1%k;
  58.                 p2 = p2%k;
  59.                 for(int p=0;p<k;p++){
  60.                         if( p == p1) continue;
  61.                         int v = classes[i][b1*k+p];
  62.                         modify(v1,v,-1);
  63.                         modify(v,v1,-1);
  64.                         modify(v2,v,1);
  65.                         modify(v,v2,1);
  66.                 }
  67.                 for(int p=0;p<k;p++){
  68.                         if( p == p2) continue;
  69.                         int v = classes[i][b2*k+p];
  70.                         modify(v2,v,-1);
  71.                         modify(v,v2,-1);
  72.                         modify(v1,v,1);
  73.                         modify(v,v1,1);
  74.                 }
  75.                 swap(classes[i][b1*k+p1],classes[i][b2*k+p2]);
  76.         }
  77.         void impri(){
  78.                 int comps = 0;
  79.                 vector < vector<int> > e(q*k);
  80.                 vector < vector<int> > cs(q*k);
  81.                 vector <int> c(q*k);
  82.                 for(int i=0;i<q*k;i++){
  83.                         for(int j=0;j<q*k;j++){
  84.                                 if(a[i][j] == 0) e[i].push_back(j);
  85.                         }
  86.                 }
  87.                 for(int i=0;i<q*k;i++){
  88.                         if( c[i] == 0){
  89.                                 comps++;
  90.                                 deque <int> B;
  91.                                 B.push_back(i);
  92.                                 cs[comps].push_back(i);
  93.                                 c[i] = comps;
  94.                                 while( !B.empty() ){
  95.                                         int x = B.front();
  96.                                         B.pop_front();
  97.                                         for(int y: e[x]){
  98.                                                 if( c[y] ) continue;
  99.                                                 c[y] = comps;
  100.                                                 cs[comps].push_back(y);
  101.                                                 B.push_back(y);
  102.                                         }
  103.                                 }
  104.                         }
  105.                 }
  106.                 for(int i=1;i<=comps;i++){
  107.                         if( cs[i].size() > 5) return;
  108.                 }
  109.                 cout << cost << "\n";
  110.                 for(int i=0;i<r;i++){
  111.                         cout << "Class " << i << ": ";
  112.                         for(int j=0;j<q;j++){
  113.                                 for(int p=0;p<k;p++){
  114.                                         cout <<  classes[i][j*k+p] << " ";
  115.                                 }
  116.                                 cout  << "| ";
  117.                         }
  118.                         cout << "\n";
  119.                 }
  120.                 cout << "Components formed by missing edges\n";
  121.                 for(int i=1;i<=comps;i++){
  122.                         if( cs[i].size() == 1) continue;
  123.                         cout << "component : ";
  124.                         for(int x: cs[i]){
  125.                                 cout << x << " ";
  126.                         }
  127.                         cout << "\n";
  128.                 }
  129.         }
  130.  
  131. };
  132.  
  133. double randomdouble(){
  134.         return rand()/ (RAND_MAX +1.);
  135. }
  136.  
  137. int flip(int delta,int i){ // does a coin flip with probability e^(delta/c_i)
  138.         double ci = 0.5* pow(0.99,pow(10,-4)*i);
  139.         double p = exp(delta/ci);
  140.         if( randomdouble() < p ) return 1;
  141.         return 0;
  142. }
  143.  
  144.  
  145.  
  146. int nextsiman( pardes& D, int i){ // this function gives us the next term in the search
  147.         int q = D.q, k = D.k, r = D.r;
  148.         // first select a random class
  149.         int x = rand()%r;
  150.         // next select two points in different blocks
  151.         int p1,p2;
  152.         while( true ){
  153.                 p1 = rand()%(k*q);
  154.                 p2 = rand()%(k*q);
  155.                 if( p1/k != p2/k) break;
  156.         }
  157.         int oldcost = D.cost;
  158.         // now consider the design in which those blocks are swapped
  159.         D.transpose(x,p1,p2);
  160.         int newcost =  D.cost;
  161.         double delta = (oldcost - newcost);
  162.         if( delta >= 0 ) return 1;
  163.         if( flip(delta,i) ) return 1;
  164.         else D.transpose(x,p1,p2);
  165.         return 0;
  166. }
  167.  
  168. pardes tryfind(int q, int k, int r){
  169.         // this method tries to find a covering design resolvable in r classes
  170.         // utilizing the simmulated annealing method discussed in the article
  171.         vector < pardes > starters; // these are the designs from which the system starts out  
  172.         int T = 1;
  173.         // our first approach starts out with a set of T random coverings
  174.         for(int i=0;i<T;i++){ // we are creating our starting designs
  175.                 pardes D(q,k,r);
  176.                 for(int j=0;j<r;j++){
  177.                         random_shuffle(D.classes[j].begin(),D.classes[j].end()); // randomly shuffle each class
  178.                 }
  179.                 D.builda();
  180.                 D.setcost();
  181.                 starters.push_back(D);
  182.         }
  183.  
  184.         int depth = 800000; // how deep we are willing to go in the search
  185.  
  186.         pardes Best = starters[0];
  187.  
  188.         vector < pardes> temp;
  189.         for(  pardes D : starters ){
  190.                 for(int i=0;i< depth;){
  191.                         i += nextsiman(D,i);
  192.                         if( D.cost < Best.cost ){
  193.                                 Best = D;
  194.                         }
  195.                         if( D.cost < 10 ){
  196.                                 D.impri();
  197.                         }
  198.                 }
  199.                 temp.push_back(D);
  200.         }
  201.         starters = temp;
  202.         return Best;
  203.  
  204. }
  205.  
  206. int main(){
  207.         srand(time(0));
  208.         int k = 5;
  209.         int q = 6;
  210.         int r ;
  211.         cout << "Insert r\n";
  212.         cin >> r;
  213.         pardes D = tryfind(q,k,r);
  214.         cout << D.cost << endl;
  215.         D.impri();
  216. }
  217.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement