Advertisement
Guest User

Untitled

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