Advertisement
eogenio777

Untitled

Nov 21st, 2020
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.92 KB | None | 0 0
  1. #pragma comment(lib, "dir/bdd.lib") // подключение библиотеки
  2. #include "bdd.h"
  3.  
  4. //main7...cpp:
  5.  
  6. #include <iostream>
  7. #include <cmath>
  8. #include <vector>
  9.  
  10.  
  11. const size_t N = 9;
  12. const size_t M = 4;
  13. const size_t N_SQRT = static_cast<size_t>(sqrt(N));
  14. const size_t K = 21;
  15.  
  16. //const int LOG_N = 4;// static_cast<int>(std::ceil(std::log2(N)));
  17. const int LOG_N = static_cast<int>(std::ceil(std::log10(N)/std::log10(2)));//T
  18.  
  19. const size_t N_VAR = 144; // N * M * LOG_N
  20. char var[N_VAR];
  21.  
  22. enum NeighbourRelations
  23. {
  24.   UP,
  25.   DOWN,
  26.   LEFT,
  27.   RIGHT
  28. };
  29.  
  30. void init(bdd p[M][N][N]);
  31. bdd limitation_1(const bdd p[M][N][N], const int propertyNumber, const int objectNumber, const int propertyValue);
  32. bdd limitation_2(const bdd p[M][N][N], const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2);
  33. bdd limitation_3(const bdd p[M][N][N], const NeighbourRelations neighbour, const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2);
  34. bdd limitation_4(const bdd p[M][N][N], const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2);
  35. void limitation_5(bdd& tree, const bdd p[M][N][N]);
  36. bdd limitation_6(const bdd p[M][N][N]);
  37. bdd limitation_7(const bdd p[M][N][N]);
  38.  
  39. void fun(char* varset, int size);
  40.  
  41. int main()
  42. {
  43.  
  44.   bdd_init(50000000, 1000000);
  45.   bdd_setcacheratio(100);
  46.   bdd_setvarnum(N_VAR);
  47.   bdd p[M][N][N];
  48.  
  49.   init(p);
  50.  
  51.   bdd task = bddtrue;
  52.  
  53.   //variant 1: n1 = 3, n2 = 2, n3 = 5, n4 = 5
  54.  
  55.   //3 type-1 limitations
  56.   task &= limitation_1(p, 1, 4, 8);
  57.   task &= limitation_1(p, 2, 0, 5);
  58.   task &= limitation_1(p, 3, 2, 5);
  59.  
  60.   //additional type-1 limitations
  61.   task &= limitation_1(p, 0, 7, 1);
  62.   task &= limitation_1(p, 2, 3, 1);
  63.   task &= limitation_1(p, 0, 2, 6);
  64.   task &= limitation_1(p, 0, 1, 5);
  65.   task &= limitation_1(p, 2, 8, 6);
  66.   task &= limitation_1(p, 1, 5, 1);
  67.   task &= limitation_1(p, 3, 6, 6);
  68.   task &= limitation_1(p, 1, 7, 3);
  69.   task &= limitation_1(p, 1, 0, 0);
  70.   task &= limitation_1(p, 0, 5, 3);
  71.   task &= limitation_1(p, 3, 1, 0);
  72.   task &= limitation_1(p, 0, 0, 7);
  73.   task &= limitation_1(p, 1, 1, 4);
  74.   task &= limitation_1(p, 2, 1, 0);
  75.  
  76.   //2 type-2 limitations
  77.   task &= limitation_2(p, 0, 0, 2, 3);
  78.   task &= limitation_2(p, 1, 5, 3, 3);
  79.  
  80.   //additional type-2 limitations
  81.   task &= limitation_2(p, 0, 6, 2, 8);
  82.  
  83.   //5 type-3 limitations
  84.   task &= limitation_3(p, NeighbourRelations::LEFT, 0, 7, 1, 2);
  85.   task &= limitation_3(p, NeighbourRelations::RIGHT, 1, 8, 3, 2);
  86.   task &= limitation_3(p, NeighbourRelations::UP, 3, 7, 0, 5);
  87.   task &= limitation_3(p, NeighbourRelations::DOWN, 2, 4, 0, 1);
  88.   task &= limitation_3(p, NeighbourRelations::RIGHT, 2, 7, 1, 0);
  89.  
  90.   //additional type-3 limitations
  91.  /* task &= limitation_3(p, NeighbourRelations::RIGHT, 1, 6, 2, 0);
  92.   task &= limitation_3(p, NeighbourRelations::DOWN, 0, 2, 0, 4);
  93. */
  94. //5 type-4 limitations
  95.   task &= limitation_4(p, 0, 4, 1, 0);
  96.   task &= limitation_4(p, 0, 8, 1, 2);
  97.   task &= limitation_4(p, 2, 4, 3, 4);
  98.   task &= limitation_4(p, 2, 6, 1, 1);
  99.   task &= limitation_4(p, 3, 0, 0, 8);
  100.  
  101.   task &= limitation_6(p);
  102.   task &= limitation_7(p);
  103.   limitation_5(task, p);
  104.  
  105.   size_t satcount = static_cast<size_t>(bdd_satcount(task));
  106.   std::cout << satcount << " solutions:\n" << std::endl;
  107.   if (satcount) bdd_allsat(task, fun);
  108.  
  109.   bdd_done();
  110.   system("pause");
  111. }
  112.  
  113.  
  114. void init(bdd p[M][N][N])
  115. {
  116.   size_t I = 0;
  117.   for (size_t i = 0; i < N; ++i) {
  118.     for (size_t j = 0; j < N; ++j) {
  119.       for (size_t z = 0; z < M; ++z) {
  120.         p[z][i][j] = bddtrue;
  121.         for (size_t k = 0; k < LOG_N; ++k) {
  122.           p[z][i][j] &= ((j >> k) & 1) ? bdd_ithvar(I + LOG_N * z + k) : bdd_nithvar(I + LOG_N * z + k);
  123.         }
  124.       }
  125.     }
  126.     I += LOG_N * M;
  127.   }
  128. }
  129.  
  130. bdd limitation_1(const bdd p[M][N][N], const int propertyNumber, const int objectNumber, const int propertyValue)
  131. {
  132.   return p[propertyNumber][objectNumber][propertyValue];
  133. }
  134.  
  135. bdd limitation_2(const bdd p[M][N][N], const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2)
  136. {
  137.   bdd tree = bddtrue;
  138.  
  139.   for (size_t i = 0; i < N; ++i) {
  140.     tree &= !(p[propertyNumber1][i][propertyValue1] ^ p[propertyNumber2][i][propertyValue2]);
  141.   }
  142.   return tree;
  143. }
  144.  
  145. bdd limitation_3(const bdd p[M][N][N], const NeighbourRelations neighbour, const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2)
  146. {
  147.   bdd tree = bddtrue;
  148.  
  149.   switch (neighbour) {
  150.   case UP:
  151.     for (size_t i = N_SQRT; i < N; ++i) {
  152.       tree &= !(p[propertyNumber1][i][propertyValue1] ^ p[propertyNumber2][i - N_SQRT][propertyValue2]);
  153.     }
  154.     break;
  155.  
  156.   case DOWN:
  157.     for (size_t i = 0; i < N - N_SQRT; ++i) {
  158.       tree &= (!p[propertyNumber1][i][propertyValue1] ^ p[propertyNumber2][i + N_SQRT][propertyValue2]);
  159.     }
  160.     break;
  161.  
  162.   case LEFT:
  163.     for (size_t i = 0; i < N; ++i) {
  164.       if (i % N_SQRT != 0) {
  165.         tree &= !(p[propertyNumber1][i][propertyValue1] ^ p[propertyNumber2][i - 1][propertyValue2]);
  166.       }
  167.     }
  168.     break;
  169.  
  170.   case RIGHT:
  171.     for (size_t i = 0; i < N; ++i) {
  172.       if ((i + 1) % N_SQRT != 0) {
  173.         tree &= !(p[propertyNumber1][i][propertyValue1] ^ p[propertyNumber2][i + 1][propertyValue2]);
  174.       }
  175.     }
  176.     break;
  177.   }
  178.   return tree;
  179. }
  180.  
  181. bdd limitation_4(const bdd p[M][N][N], const int propertyNumber1, const int propertyValue1, const int propertyNumber2, const int propertyValue2)
  182. {
  183.   return limitation_3(p, NeighbourRelations::UP, propertyNumber1, propertyValue1, propertyNumber2, propertyValue2) |
  184.     limitation_3(p, NeighbourRelations::DOWN, propertyNumber1, propertyValue1, propertyNumber2, propertyValue2) |
  185.     limitation_3(p, NeighbourRelations::LEFT, propertyNumber1, propertyValue1, propertyNumber2, propertyValue2) |
  186.     limitation_3(p, NeighbourRelations::RIGHT, propertyNumber1, propertyValue1, propertyNumber2, propertyValue2);
  187. }
  188.  
  189. void limitation_5(bdd& tree, const bdd p[M][N][N])
  190. {
  191.   for (size_t m = 0; m < M; ++m) {
  192.     for (size_t i = 0; i < N - 1; ++i) {
  193.       for (size_t j = i + 1; j < N; ++j) {
  194.         for (size_t k = 0; k < N; ++k) {
  195.           tree &= p[m][i][k] >> !p[m][j][k];
  196.         }
  197.       }
  198.     }
  199.   }
  200. }
  201.  
  202. bdd limitation_6(const bdd p[M][N][N])
  203. {
  204.   bdd tree = bddtrue;
  205.  
  206.   for (size_t i = 0; i < N; ++i) {
  207.     for (size_t k = 0; k < M; ++k) {
  208.       bdd temp = bddfalse;
  209.  
  210.       for (size_t j = 0; j < N; ++j) {
  211.         temp |= p[k][i][j];
  212.       }
  213.  
  214.       tree &= temp;
  215.     }
  216.   }
  217.  
  218.   return tree;
  219. }
  220.  
  221. bdd limitation_7(const bdd p[M][N][N])
  222. {
  223.   bdd task = bddtrue;
  224.  
  225.   for (int i = 0; i < N; i++) {
  226.     bdd temp = bddfalse;
  227.     for (int j1 = 0; j1 < N; j1++) {
  228.       for (int j2 = 0; j2 < N; j2++) {
  229.         for (int j3 = 0; j3 < N; j3++) {
  230.           for (int j4 = 0; j4 < N; j4++) {
  231.             if (j1 + j2 + j3 + j4 <= K) {
  232.               temp |= (p[0][i][j1] & p[1][i][j2] & p[2][i][j3] & p[3][i][j4]);
  233.             }
  234.           }
  235.         }
  236.       }
  237.     }
  238.     task &= temp;
  239.   }
  240.  
  241.   return task;
  242. }
  243.  
  244. void print()
  245. {
  246.   for (size_t i = 0; i < N; i++) {
  247.     std::cout << i << ": ";
  248.     for (size_t j = 0; j < M; j++) {
  249.       int J = i * M * LOG_N + j * LOG_N;
  250.       int num = 0;
  251.       for (size_t k = 0; k < LOG_N; k++) num += static_cast<size_t>(var[J + k] << k);
  252.       std::cout << num << ' ';
  253.     }
  254.     std::cout << "\n";
  255.   }
  256.   std::cout << "\n";
  257. }
  258.  
  259. void build(char* varset, unsigned n, unsigned I)
  260. {
  261.   if (I == n - 1) {
  262.     if (varset[I] >= 0) {
  263.       var[I] = varset[I];
  264.       print();
  265.       return;
  266.     }
  267.  
  268.     var[I] = 0;
  269.     print();
  270.     var[I] = 1;
  271.     print();
  272.     return;
  273.   }
  274.  
  275.   if (varset[I] >= 0) {
  276.     var[I] = varset[I];
  277.     build(varset, n, I + 1);
  278.     return;
  279.   }
  280.  
  281.   var[I] = 0;
  282.   build(varset, n, I + 1);
  283.   var[I] = 1;
  284.   build(varset, n, I + 1);
  285. }
  286.  
  287. void fun(char* varset, int size)
  288. {
  289.   build(varset, size, 0);
  290. }
  291.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement