Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.47 KB | None | 0 0
  1. // AIProject.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3.  
  4. #include "pch.h"
  5. #include <iostream>
  6. #include <vector>
  7. #include <fstream>
  8. #include <string>
  9. #include <queue>
  10.  
  11. using namespace std;
  12.  
  13. struct stateData {
  14. int heuristic;
  15. int depth;
  16. vector<vector<int>> state = { {0, 0, 0} , {0,0,0}, {0,0,0} };
  17. vector<char> directionSequence;
  18. vector<int> heuristicSequence;
  19.  
  20.  
  21. stateData() {}
  22. stateData(int heuristic, char direction) : heuristic(heuristic) {}
  23.  
  24. };
  25.  
  26. struct compareHeuristic {
  27. bool operator()(stateData const& p1, stateData const& p2) {
  28. return p1.heuristic > p2.heuristic;
  29. }
  30. };
  31.  
  32. void printTile(vector<vector<int>> tile) {
  33. for (int i = 0; i < 3; i++) {
  34. for (int j = 0; j < 3; j++) {
  35. cout << tile[i][j] << " ";
  36. }
  37. cout << endl;
  38. }
  39. cout << endl;
  40. return;
  41. }
  42.  
  43. bool checkGoal(vector<vector<int>> initial, vector<vector<int>> goal) {
  44. for (int i = 0; i < initial.size(); i++) {
  45. for (int j = 0; j < initial[i].size(); j++) {
  46. if (initial[i][j] != goal[i][j]) {
  47. return false;
  48. }
  49. }
  50. }
  51. return true;
  52. }
  53.  
  54.  
  55. //Heuristic Function (1) --> Sum of Manhattan Distances of tiles from their goal position
  56. int heuristicHelper(vector<vector<int>>& init, vector<vector<int>>& goal, int i, int j) {
  57. for (int gi = 0; gi < 3; gi++) {
  58. for (int gj = 0; gj < 3; gj++) {
  59. if (goal[gi][gj] == init[i][j]) {
  60. //cout << i << " and " << j << endl;
  61. //cout << gi << " et " << gj << endl;
  62. return abs(gi - i) + abs(gj - j);
  63.  
  64. }
  65. }
  66. }
  67. return 0;
  68. }
  69.  
  70. int heuristicfunc(vector<vector<int>>& init, vector<vector<int>>& goal) {
  71. int heurVal = 0;
  72. for (int i = 0; i < 3; i++) {
  73. for (int j = 0; j < 3; j++) {
  74. if (init[i][j] != goal[i][j] && init[i][j] != 0) {
  75. heurVal += heuristicHelper(init, goal, i, j);
  76. }
  77. }
  78. }
  79.  
  80. return heurVal;
  81. }
  82.  
  83. //On same line and goal positions are both in that line
  84. bool check1(int i, int j, int i1, int j1, vector<vector<int>> &init, vector<vector<int>>& goal) {
  85. if (i1 == i || j1 == j) {
  86. int val1 = init[i][j];
  87. int val2 = init[i1][j1];
  88.  
  89. int row1;
  90. int col1;
  91. int row2;
  92. int col2;
  93.  
  94. for (int gi = 0; gi < 3; gi++) {
  95. for (int gj = 0; gj < 3; gj++) {
  96. if (goal[gi][gj] == val1) {
  97. row1 = gi;
  98. col1 = gj;
  99. }
  100. if (goal[gi][gj] == val2) {
  101. row2 = gi;
  102. col2 = gj;
  103. }
  104. }
  105. }
  106.  
  107. if (i1 == i) {
  108. if (row1 == i && row2 == i1) {
  109. return true;
  110. }
  111. }
  112.  
  113. if (j1 == j) {
  114. if (col1 == j && col2 == j1) {
  115. return true;
  116. }
  117. }
  118.  
  119. }
  120. return false;
  121. }
  122.  
  123. //Goal position of tj and tk on same line
  124. //Then if they are, check for a block
  125. bool check2(int i, int j, int i1, int j1, vector<vector<int>> &init, vector<vector<int>>& goal) {
  126. int val1 = init[i][j];
  127. int val2 = init[i1][j1];
  128.  
  129. int initindex1;
  130. int initindex2;
  131. int goalindex2;
  132. int goalindex1;
  133.  
  134. vector<int> init1D;
  135. vector<int> goal1D;
  136.  
  137. //1D construction
  138. for (int gi = 0; gi < 3; gi++) {
  139. for (int gj = 0; gj < 3; gj++) {
  140.  
  141. init1D.push_back(init[gi][gj]);
  142. goal1D.push_back(goal[gi][gj]);
  143. }
  144. }
  145.  
  146. //Find goal indices
  147. for (int gi = 0; gi < 9; gi++) {
  148. if (init1D[gi] == val1) {
  149. initindex1 = gi;
  150. }
  151. if (init1D[gi] == val2) {
  152. initindex2 = gi;
  153. }
  154.  
  155. if (goal1D[gi] == val1) {
  156. goalindex1 = gi;
  157. }
  158. if (goal1D[gi] == val2) {
  159. goalindex2 = gi;
  160. }
  161. }
  162.  
  163. //AT GOAL POSITIONS
  164. if (initindex1 == goalindex1 && initindex2 == goalindex2) {
  165. return false;
  166. }
  167.  
  168.  
  169. //Goal pos of tj + tk on same line as eval line
  170. if ((initindex1 > initindex2 && goalindex2 >= goalindex1) || (initindex2 > initindex1 && goalindex1 >= goalindex2)) {
  171. return true;
  172. }
  173.  
  174.  
  175.  
  176. //No linear conflict
  177. return false;
  178.  
  179. }
  180.  
  181.  
  182. //Heuristic Function (2) --> Sum of Manhattan Distances of tiles from their goal position + 2 * (# of linear conflicts)
  183. int heuristicfunc2(vector<vector<int>>& init, vector<vector<int>>& goal) {
  184. int heurVal = heuristicfunc(init, goal); //First portion
  185. //Now to find linear conflict
  186.  
  187.  
  188. int linearConflict = 0;
  189. for (int i = 0; i < 3; i++) {
  190. for (int j = 0; j < 3; j++) {
  191.  
  192. for (int i1 = i; i1 < 3; i1++) {
  193. for (int j1 = j; j1 < 3; j1++) {
  194.  
  195. //Check to make sure they are not same tile
  196. if (!(i1 == i && j1 == j) && init[i][j] != 0 && init[i1][j1] != 0) {
  197. if (check1(i, j, i1, j1, init, goal)) {
  198. if (check2(i, j, i1, j1, init, goal)) {
  199. //cout << init[i][j] << " " << init[i1][j1] << endl;
  200. linearConflict++;
  201. }
  202. }
  203. }
  204. }
  205. }
  206.  
  207.  
  208. }
  209. }
  210. //cout << linearConflict << endl;
  211. return heurVal + 2 * linearConflict;
  212. }
  213.  
  214. //No recursion!!!
  215. stateData aStarSearch(stateData initial, stateData goal, int& numNodes, priority_queue< stateData, vector< stateData>, compareHeuristic>& priQ) {
  216. char lastMove = 'N';
  217.  
  218.  
  219. while (!(priQ.empty())) {
  220.  
  221. stateData evaluation = priQ.top();
  222. priQ.pop();
  223.  
  224. //Done Check!!!!!
  225. if (checkGoal(evaluation.state, goal.state)) {
  226. return evaluation;
  227. }
  228.  
  229.  
  230. //Find 0 position
  231. int row = 0;
  232. int col = 0;
  233. for (int i = 0; i < 3; i++) {
  234. for (int j = 0; j < 3; j++) {
  235. if (evaluation.state[i][j] == 0) {
  236. row = i;
  237. col = j;
  238. break;
  239. }
  240. }
  241. }
  242.  
  243. //Movement evaluation
  244. bool up = true;
  245. bool down = true;
  246. bool left = true;
  247. bool right = true;
  248.  
  249. if (row == 0) {
  250. up = false;
  251. }
  252. else if (row == 2) {
  253. down = false;
  254. }
  255.  
  256. if (col == 0) {
  257. left = false;
  258. }
  259. else if (col == 2) {
  260. right = false;
  261. }
  262.  
  263. //Kill Repeated Movements!!!!!
  264. if (lastMove != 'N') {
  265.  
  266. if (lastMove == 'U') {
  267. down = false;
  268. }
  269. else if (lastMove == 'D') {
  270. up = false;
  271. }
  272. else if (lastMove == 'L') {
  273. right = false;
  274. }
  275. else if (lastMove == 'R') {
  276. left = false;
  277. }
  278. }
  279.  
  280.  
  281. //Find children and Heuristic evaluations!
  282. //Heuristic Evaluation
  283. //h(n) is from the heuristic func
  284. //Since g(n) is just total path cost from root to node, we can use depth+1 as the resultant
  285. int heurVal = 0;
  286. char direction;
  287.  
  288. if (up) {
  289. //Two swaps to correct everything
  290. swap(evaluation.state[row - 1][col], evaluation.state[row][col]);
  291. heurVal = heuristicfunc2(evaluation.state, goal.state);
  292. direction = 'U';
  293. stateData child1 = evaluation;
  294. child1.directionSequence.push_back(direction);
  295. child1.heuristic = heurVal + evaluation.depth + 1;
  296. child1.depth += 1;
  297. child1.heuristicSequence.push_back(heurVal + evaluation.depth + 1);
  298.  
  299.  
  300.  
  301. priQ.push(child1);
  302. swap(evaluation.state[row - 1][col], evaluation.state[row][col]);
  303. numNodes++;
  304. }
  305. if (down) {
  306. //Two swaps to correct everything
  307. swap(evaluation.state[row + 1][col], evaluation.state[row][col]);
  308. heurVal = heuristicfunc2(evaluation.state, goal.state);
  309. direction = 'D';
  310. stateData child2 = evaluation;
  311. child2.directionSequence.push_back(direction);
  312. child2.heuristic = heurVal + evaluation.depth + 1;
  313. child2.depth += 1;
  314. child2.heuristicSequence.push_back(heurVal + evaluation.depth + 1);
  315.  
  316. priQ.push(child2);
  317. swap(evaluation.state[row + 1][col], evaluation.state[row][col]);
  318. numNodes++;
  319. }
  320. if (left) {
  321. //Two swaps to correct everything
  322. swap(evaluation.state[row][col - 1], evaluation.state[row][col]);
  323. heurVal = heuristicfunc2(evaluation.state, goal.state);
  324. direction = 'L';
  325. stateData child3 = evaluation;
  326. child3.directionSequence.push_back(direction);
  327. child3.heuristic = heurVal + evaluation.depth + 1;
  328. child3.depth += 1;
  329. child3.heuristicSequence.push_back(heurVal + evaluation.depth + 1);
  330.  
  331.  
  332. priQ.push(child3);
  333. swap(evaluation.state[row][col - 1], evaluation.state[row][col]);
  334. numNodes++;
  335. }
  336. if (right) {
  337. //Two swaps to correct everything
  338. swap(evaluation.state[row][col + 1], evaluation.state[row][col]);
  339. heurVal = heuristicfunc2(evaluation.state, goal.state);
  340. direction = 'R';
  341. stateData child4 = evaluation;
  342. child4.directionSequence.push_back(direction);
  343. child4.heuristic = heurVal + evaluation.depth + 1;
  344. child4.depth += 1;
  345. child4.heuristicSequence.push_back(heurVal + evaluation.depth + 1);
  346.  
  347.  
  348. priQ.push(child4);
  349. swap(evaluation.state[row][col + 1], evaluation.state[row][col]);
  350. numNodes++;
  351. }
  352.  
  353. lastMove = priQ.top().directionSequence[priQ.top().directionSequence.size() - 1];
  354.  
  355.  
  356. }
  357.  
  358. return initial;
  359. }
  360.  
  361.  
  362.  
  363. void inFile(vector<vector<int>>& initial, vector<vector<int>>& goal, string documentName) {
  364. ifstream myfile;
  365. myfile.open(documentName);
  366. if (!myfile) {
  367. cerr << "Unable to open file datafile.txt";
  368. exit(1); // call system to stop
  369. }
  370. int value = 0;
  371. for (int i = 0; i < 3; i++) {
  372. for (int j = 0; j < 3; j++) {
  373. myfile >> value;
  374. initial[i][j] = value;
  375. }
  376. }
  377.  
  378. for (int i = 0; i < 3; i++) {
  379. for (int j = 0; j < 3; j++) {
  380. myfile >> value;
  381. goal[i][j] = value;
  382. }
  383. }
  384.  
  385. myfile.close();
  386. }
  387.  
  388. int main()
  389. {
  390. vector<vector<int>> initialState = { {0, 0, 0} , {0,0,0}, {0,0,0} };
  391. vector<vector<int>> goalState = { {0, 0, 0} , {0,0,0}, {0,0,0} };
  392.  
  393. string documentName;
  394.  
  395.  
  396.  
  397. cout << "Enter a file name: " << endl;
  398. cin >> documentName;
  399.  
  400. inFile(initialState, goalState, documentName);
  401.  
  402. stateData initial;
  403. stateData goal;
  404.  
  405. initial.state = initialState;
  406. goal.state = goalState;
  407.  
  408.  
  409. int numNodes = 1;
  410. int depth = 0;
  411.  
  412. int newHeur = heuristicfunc2(initial.state, goal.state);
  413. initial.heuristic = newHeur;
  414. initial.heuristicSequence.push_back(newHeur);
  415. initial.depth = depth;
  416.  
  417.  
  418.  
  419. priority_queue< stateData, vector< stateData>, compareHeuristic> priQ;
  420. priQ.push(initial);
  421.  
  422.  
  423. stateData solution = aStarSearch(initial, goal, numNodes, priQ);
  424.  
  425.  
  426. cout << solution.depth << endl;
  427. cout << numNodes << endl;
  428.  
  429. for (size_t i = 0; i < solution.directionSequence.size(); i++) {
  430. cout << solution.directionSequence[i] << " ";
  431. }
  432. cout << endl;
  433. for (size_t i = 0; i < solution.directionSequence.size(); i++) {
  434. cout << solution.heuristicSequence[i] << " ";
  435. }
  436.  
  437. cout << endl;
  438.  
  439.  
  440. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement