Advertisement
Guest User

Untitled

a guest
May 27th, 2015
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.10 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <iomanip>
  5. #include <math.h>
  6. #include <ctime>
  7. #include <string>
  8. #include <queue>
  9.  
  10.  
  11. using namespace std;
  12.  
  13. const int IDIM = 15; // horizontal size of the squares
  14. const int JDIM = 15; // vertical size size of the squares
  15. const int NDIR = 4; // number of possible directions to go at any position
  16.  
  17. // if NDIR = 4
  18. const int iDir[NDIR] = {1, 0, -1, 0};
  19. const int jDir[NDIR] = {0, 1, 0, -1};
  20.  
  21. // if NDIR = 8
  22. //const int iDir[NDIR] = {1, 1, 0, -1, -1, -1, 0, 1};
  23. //const int jDir[NDIR] = {0, 1, 1, 1, 0, -1, -1, -1};
  24.  
  25. int squares[IDIM][JDIM];
  26.  
  27. // list of closed (check-out) nodes
  28. int closedNodes[IDIM][JDIM];
  29.  
  30. // list of open (not-yet-checked-out) nodes
  31. int openNodes[IDIM][JDIM];
  32.  
  33. // map of directions (0: East, 1: North, 2: West, 3: South)
  34. int dirMap[IDIM][JDIM];
  35.  
  36. struct Location
  37. {
  38. int row, col;
  39.  
  40. Location()
  41. {
  42. row = col = 0;
  43. };
  44.  
  45. Location(int r, int c)
  46. {
  47. row = r;
  48. col = c;
  49. };
  50. };
  51.  
  52. class Node
  53. {
  54. // current position
  55. int rPos;
  56. int cPos;
  57.  
  58. // total distance already travelled to reach the node
  59. int GValue;
  60.  
  61. // FValue = GValue + remaining distance estimate
  62. int FValue; // smaller FValue gets priority
  63.  
  64. public:
  65. Node(const Location &loc, int g, int f)
  66. {rPos = loc.row; cPos = loc.col; GValue = g; FValue = f;}
  67.  
  68. Location getLocation() const {return Location(rPos,cPos);}
  69. int getGValue() const {return GValue;}
  70. int getFValue() const {return FValue;}
  71.  
  72. void calculateFValue(const Location& locDest)
  73. {
  74. FValue = GValue + getHValue(locDest) * 10;
  75. }
  76.  
  77.  
  78. void updateGValue(const int & i) // i: direction
  79. {
  80. GValue += (NDIR == 8 ? (i % 2 == 0 ? 10 : 14) : 10);
  81. }
  82.  
  83. // Estimation function for the remaining distance to the goal.
  84. const int & getHValue(const Location& locDest) const
  85. {
  86. static int rd, cd, d;
  87. rd = locDest.row - rPos;
  88. cd = locDest.col - cPos;
  89.  
  90. // Euclidian Distance
  91. // d = static_cast<int>(sqrt((double)(rd*rd+cd*cd)));
  92.  
  93. // Manhattan distance
  94. d = abs(rd) + abs(cd);
  95.  
  96. // Chebyshev distance
  97. //d = max(abs(rd), abs(cd));
  98.  
  99. return(d);
  100. }
  101.  
  102. // Determine FValue (in the priority queue)
  103. friend bool operator<(const Node & a, const Node & b)
  104. {
  105. return a.getFValue() > b.getFValue();
  106. }
  107. };
  108.  
  109. // A-star algorithm.
  110. // The path returned is a string of direction digits.
  111. string pathFind( const Location &locStart ,
  112. const Location &locFinish )
  113.  
  114. {
  115. // list of open (not-yet-checked-out) nodes
  116. static priority_queue<Node> q[2];
  117.  
  118. // q index
  119. static int qi;
  120.  
  121. static Node* pNode1;
  122. static Node* pNode2;
  123. static int i, j, row, col, iNext, jNext;
  124. static char c;
  125. qi = 0;
  126.  
  127. // reset the Node lists (0 = ".")
  128. for(j = 0; j < JDIM; j++) {
  129. for(i = 0; i < IDIM; i++) {
  130. closedNodes[i][j] = 0;
  131. openNodes[i][j] = 0;
  132. }
  133. }
  134.  
  135. // create the start node and push into list of open nodes
  136. pNode1 = new Node(locStart, 0, 0);
  137. pNode1->calculateFValue(locFinish);
  138. q[qi].push(*pNode1);
  139.  
  140. // A* search
  141. while(!q[qi].empty()) {
  142. // get the current node w/ the lowest FValue
  143. // from the list of open nodes
  144. pNode1 = new Node( q[qi].top().getLocation(),
  145. q[qi].top().getGValue(), q[qi].top().getFValue());
  146.  
  147. row = (pNode1->getLocation()).row;
  148. col = pNode1->getLocation().col;
  149. cout << "row, col=" << row << "," << col << endl;
  150.  
  151. // remove the node from the open list
  152. q[qi].pop();
  153. openNodes[row][col] = 0;
  154.  
  155. // mark it on the closed nodes list
  156. closedNodes[row][col] = 1;
  157.  
  158. // stop searching when the goal state is reached
  159. if(row == locFinish.row && col == locFinish.col) {
  160. // drawing direction map
  161. cout << endl;
  162. for(j = JDIM - 1; j >= 0; j--) {
  163. for(i = 0; i < IDIM; i++) {
  164. cout << dirMap[i][j];
  165. }
  166. cout << endl;
  167. }
  168. cout << endl;
  169.  
  170. // generate the path from finish to start from dirMap
  171. string path = "";
  172. while(!(row == locStart.row && col == locStart.col)) {
  173. j = dirMap[row][col];
  174. c = '0' + (j + NDIR/2) % NDIR;
  175. path = c + path;
  176. row += iDir[j];
  177. col += jDir[j];
  178. }
  179.  
  180. // garbage collection
  181. delete pNode1;
  182.  
  183. // empty the leftover nodes
  184. while(!q[qi].empty()) q[qi].pop();
  185. return path;
  186. }
  187.  
  188. // generate moves in all possible directions
  189. for(i = 0; i < NDIR; i++) {
  190. iNext = row + iDir[i];
  191. jNext = col + jDir[i];
  192.  
  193. // if not wall (obstacle) nor in the closed list
  194. if(!(iNext < 0 || iNext > IDIM - 1 || jNext < 0 || jNext > JDIM - 1 ||
  195. squares[iNext][jNext] == 1 || closedNodes[iNext][jNext] == 1)) {
  196.  
  197. // generate a child node
  198. pNode2 = new Node( Location(iNext, jNext), pNode1->getGValue(), pNode1->getFValue());
  199. pNode2->updateGValue(i);
  200. pNode2->calculateFValue(locFinish);
  201.  
  202. // if it is not in the open list then add into that
  203. if(openNodes[iNext][jNext] == 0) {
  204. openNodes[iNext][jNext] = pNode2->getFValue();
  205. q[qi].push(*pNode2);
  206. // mark its parent node direction
  207. dirMap[iNext][jNext] = (i + NDIR/2) % NDIR;
  208. }
  209.  
  210. // already in the open list
  211. else if(openNodes[iNext][jNext] > pNode2->getFValue()) {
  212. // update the FValue info
  213. openNodes[iNext][jNext] = pNode2->getFValue();
  214.  
  215. // update the parent direction info, mark its parent node direction
  216. dirMap[iNext][jNext] = (i + NDIR/2) % NDIR;
  217.  
  218. // replace the node by emptying one q to the other one
  219. // except the node to be replaced will be ignored
  220. // and the new node will be pushed in instead
  221. while(!(q[qi].top().getLocation().row == iNext &&
  222. q[qi].top().getLocation().col == jNext)) {
  223. q[1 - qi].push(q[qi].top());
  224. q[qi].pop();
  225. }
  226.  
  227. // remove the wanted node
  228. q[qi].pop();
  229.  
  230. // empty the larger size q to the smaller one
  231. if(q[qi].size() > q[1 - qi].size()) qi = 1 - qi;
  232. while(!q[qi].empty()) {
  233. q[1 - qi].push(q[qi].top());
  234. q[qi].pop();
  235. }
  236. qi = 1 - qi;
  237.  
  238. // add the better node instead
  239. q[qi].push(*pNode2);
  240. }
  241. else delete pNode2;
  242. }
  243. }
  244. delete pNode1;
  245. }
  246. // no path found
  247. return "";
  248. }
  249.  
  250. int main()
  251. {
  252. // create empty squares
  253. for(int j = 0; j < JDIM; j++) {
  254. for(int i = 0; i < IDIM; i++) squares[i][j] = 0;
  255. }
  256.  
  257. // make wall
  258. squares[4][2] = 1;
  259. squares[4][3] = 1;
  260. squares[4][4] = 1;
  261.  
  262. // starting and ending positions
  263. int iStart = 2,jStart = 3;
  264. int iEnd = 6,jEnd = 3;
  265.  
  266. cout << "Grid Size (IDIM,JDIM): "<< IDIM<< "," << JDIM << endl;
  267. cout << "Start: " << iStart<<","<< jStart << endl;
  268. cout << "Finish: " << iEnd<<","<< jEnd << endl;
  269.  
  270. clock_t start = clock();
  271.  
  272. // get the path
  273. string path = pathFind(Location(iStart, jStart), Location(iEnd, jEnd));
  274.  
  275. clock_t end = clock();
  276. double time = double(end - start);
  277. cout << "Time (ms): "<< time << endl;
  278. cout << "path: " << path << endl;
  279.  
  280. // follow the path on the squares and display it
  281. if(path.length() > 0) {
  282. char c;
  283. int m,n;
  284. int i = iStart;
  285. int j = jStart;
  286. squares[i][j] = 2;
  287. for(m = 0; m < path.length(); m++) {
  288. c = path.at(m);
  289. n = atoi(&c);
  290. i = i + iDir[n];
  291. j = j + jDir[n];
  292. squares[i][j] = 3;
  293. }
  294. squares[i][j] = 4;
  295.  
  296. // display the squares with the path
  297. for(j = JDIM - 1; j >= 0; j--) {
  298. for(i = 0; i < IDIM; i++) {
  299. if(squares[i][j] == 0)
  300. cout << ".";
  301. else if(squares[i][j] == 1)
  302. cout << "O"; //obstacle
  303. else if(squares[i][j] == 2)
  304. cout << "I"; //Initial
  305. else if(squares[i][j] == 3)
  306. cout << "P"; //path
  307. else if(squares[i][j] == 4)
  308. cout << "F"; //final
  309. }
  310. cout << endl;
  311. }
  312. }
  313. return(0);
  314. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement