Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.38 KB | None | 0 0
  1. #include <iostream>
  2. #include <bdd.h>
  3.  
  4. using namespace std;
  5.  
  6. #define N 9
  7. #define M 4
  8. #define LOG_N 4
  9. #define N_VAR M*N*LOG_N
  10. #define K 19
  11.  
  12. #define COL_N 3
  13.  
  14. typedef const bdd (&property)[N][N];
  15.  
  16. // n1 = 2
  17. // n2 = 4
  18. // n3 = 5
  19. // n4 = 4
  20.  
  21. bdd bound_2(property p1, int v1, property p2, int v2)
  22. {
  23.     bdd res = bddtrue;
  24.     for (int i = 0; i < N; ++i)
  25.     {
  26.         res &= !(p1[i][v1] ^ p2[i][v2]);
  27.     }
  28.     return res;
  29. }
  30.  
  31. // Рассматривается правый сосед (объект расположенный справа сверху)
  32. bdd bound_3_right_up(property p, int v, property p_n, int v_n)
  33. {
  34.     bdd res = bddtrue;
  35.  
  36.     int step = COL_N - 1;
  37.  
  38.     for (int i = 0; i < N; ++i)
  39.     {
  40.         // Элементы первого столбца или нижней строки
  41.         // не могут быть соседями справа
  42.         if (i % COL_N == 0 || i + COL_N >= N)
  43.             res &= !p_n[i][v_n];
  44.  
  45.         // Элементы первой строки или последнего столбца
  46.         // не могут иметь соседа справа
  47.         if (i < COL_N || i % COL_N == COL_N - 1)
  48.             res &= !p[i][v];
  49.  
  50.         if (i >= COL_N && i % COL_N < COL_N - 1)
  51.             res &= !(p[i][v] ^ p_n[i-step][v_n]);
  52.     }
  53.  
  54.     return res;
  55. }
  56.  
  57. // Рассматривается левый сосед (объект расположенный слева сверху)
  58. bdd bound_3_left_up(property p, int v, property p_n, int v_n)
  59. {
  60.     bdd res = bddtrue;
  61.  
  62.     int step = COL_N + 1;
  63.  
  64.     for (int i = 0; i < N; ++i)
  65.     {
  66.         // Элементы последнего столбца или нижней строки
  67.         // не могут быть соседями слева
  68.         if (i % COL_N == COL_N - 1 || i + COL_N >= N)
  69.             res &= !p_n[i][v_n];
  70.  
  71.         // Элементы первой строки или первого столбца
  72.         // не могут иметь соседа слева
  73.         if (i < COL_N || i % COL_N == 0)
  74.             res &= !p[i][v];
  75.  
  76.         if (i >= COL_N && i % COL_N > 0)
  77.             res &= !(p[i][v] ^ p_n[i-step][v_n]);
  78.     }
  79.  
  80.     return res;
  81. }
  82.  
  83. bdd bound_4(property p, int v, property p_n, int v_n)
  84. {
  85.     bdd temp1 = bound_3_left_up (p, v, p_n, v_n);
  86.     bdd temp2 = bound_3_right_up(p, v, p_n, v_n);
  87.     return temp1 | temp2;
  88. }
  89.  
  90. ostream& out = cout;
  91.  
  92. void fun(char* varset, int size);
  93.  
  94. int main()
  95. {
  96.     bdd_init(10000000, 1000000);
  97.  
  98.     bdd_setvarnum(N_VAR);
  99.  
  100.     bdd p[M][N][N];
  101.  
  102.     unsigned I = 0;
  103.     for (unsigned i = 0; i < N; i++)
  104.     {
  105.         for (unsigned j = 0; j < N; j++)
  106.         {
  107.             for (int m = 0; m < M; m++)
  108.             {
  109.                 p[m][i][j] = bddtrue;
  110.                 for (unsigned k = 0; k < LOG_N; k++) p[m][i][j] &= ((j >> k) & 1) ? bdd_ithvar(I + LOG_N * m + k) : bdd_nithvar(I + LOG_N * m + k);
  111.             }
  112.         }
  113.         I += LOG_N*M;
  114.     }
  115.  
  116.     bdd task = bddtrue;
  117.  
  118.     // Ограничение 6:
  119.     for (unsigned i = 0; i < N; i++)
  120.     {
  121.         bdd temp[M];
  122.         for (int m = 0; m < M; m++)
  123.             temp[m] = bddfalse;
  124.         for (unsigned j = 0; j < N; j++)
  125.             for (int m = 0; m < M; m++)
  126.                 temp[m] |= p[m][i][j];
  127.         for (int m = 0; m < M; m++)
  128.             task &= temp[m];
  129.     }
  130.  
  131.  
  132.     // Ограничение 1:
  133.     task &= p[0][0][0];
  134.     task &= p[0][1][1];
  135.  
  136.     task &= p[1][4][5];
  137.     task &= p[0][6][6];
  138.  
  139.  
  140.  
  141.     // Ограничение 2:
  142.     task &= bound_2(p[0], 4, p[3], 7);
  143.     task &= bound_2(p[0], 6, p[1], 7);
  144.     task &= bound_2(p[2], 4, p[3], 5);
  145.     task &= bound_2(p[0], 0, p[1], 1);
  146.  
  147.  
  148.  
  149.     // Ограничение 3:
  150.     task &= bound_3_right_up(p[0], 3, p[0], 1);
  151.     task &= bound_3_right_up(p[1], 4, p[1], 2);
  152.     task &= bound_3_left_up (p[2], 7, p[3], 4);
  153.     task &= bound_3_left_up (p[0], 8, p[3], 7);
  154.     task &= bound_3_left_up (p[3], 2, p[3], 7);
  155.  
  156.  
  157.  
  158.     // Ограничение 4:
  159.     task &= bound_4(p[0], 4, p[0], 0);
  160.     task &= bound_4(p[1], 5, p[2], 4);
  161.     task &= bound_4(p[0], 7, p[3], 8);
  162.     task &= bound_4(p[1], 8, p[1], 4);
  163.  
  164.  
  165.  
  166.     // Ограничение 7:
  167.     for (int i = 0; i < N; ++i)
  168.     {
  169.         if (i % 2 == 0)
  170.         {
  171.             bdd temp = bddfalse;
  172.             for (int j1 = 0; j1 < N; ++j1)
  173.             {
  174.                 for (int j2 = 0; j2 < N; ++j2)
  175.                     for (int j3 = 0; j3 < N; ++j3)
  176.                         for (int j4 = 0; j4 < N; ++j4)
  177.                             if (j1 + j2 + j3 + j4 <= K)
  178.                                 temp |= (p[0][i][j1] & p[1][i][j2] & p[2][i][j3] & p[3][i][j4]);
  179.             }
  180.             task &= temp;
  181.         }
  182.     }
  183.  
  184.    
  185.  
  186.     // Ограничение 5:
  187.     for (unsigned j = 0; j < N; j++)
  188.         for (unsigned i = 0; i < N - 1; i++)
  189.             for (unsigned k = i + 1; k < N; k++)
  190.             {
  191.                 cout << j << " " << i << " " << k << endl;
  192.                 for (unsigned m = 0; m < M; m++)
  193.                     task &= p[m][i][j] >> !p[m][k][j];
  194.             }
  195.  
  196.  
  197.     unsigned satcount = (unsigned)bdd_satcount(task);
  198.     out<<satcount<<" solutions:\n"<<endl;
  199.     if (satcount)
  200.         bdd_allsat(task, fun);
  201.  
  202.     bdd_done();
  203.  
  204.     getchar();
  205.  
  206.     return 0;
  207. }
  208.  
  209.  
  210. char var[N_VAR];
  211.  
  212. void print(void)
  213. {
  214.     for (unsigned i = 0; i < N; i++)
  215.     {
  216.         out<<i<<": ";
  217.         for (unsigned j = 0; j < N; j++)
  218.         {
  219.             unsigned J = i*N*LOG_N + j*LOG_N;
  220.             unsigned num = 0;
  221.             for (unsigned k = 0; k < LOG_N; k++) num += (unsigned)(var[J + k] << k);
  222.             out<<num<<' ';
  223.         }
  224.         out<<endl;
  225.     }
  226.     out<<endl;
  227. }
  228.  
  229. void build(char* varset, unsigned n, unsigned I)
  230. {
  231.     if (I == n - 1)
  232.     {
  233.         if (varset[I] >= 0)
  234.         {
  235.             var[I] = varset[I];
  236.             print();
  237.             return;
  238.         }
  239.         var[I] = 0;
  240.         print();
  241.         var[I] = 1;
  242.         print();
  243.         return;
  244.     }
  245.     if (varset[I] >= 0)
  246.     {
  247.         var[I] = varset[I];
  248.         build(varset, n, I + 1);
  249.         return;
  250.     }
  251.     var[I] = 0;
  252.     build(varset, n, I + 1);
  253.     var[I] = 1;
  254.     build(varset, n, I + 1);
  255. }
  256.  
  257. void fun(char* varset, int size)
  258. {
  259.     build(varset, size, 0);
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement