Advertisement
Guest User

Untitled

a guest
May 27th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.06 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <cmath>
  5. #include <windows.h>
  6. #include <time.h>
  7. #include <cstdio>
  8.  
  9. using namespace std;
  10.  
  11. class node{
  12. public:
  13. vector <vector <int> > state;
  14. int priority;
  15. int pre;
  16. int depth;
  17. int x;
  18. int y;
  19.  
  20. // Constructors
  21. node(){
  22. int i;
  23. this->state.resize(3);
  24. for(i=0 ; i<3 ; i++)
  25. state[i].resize(3);
  26. this->priority = 100;
  27. this->depth = 0;
  28. this->pre = -1 ;
  29. this->x=0;
  30. this->y=0;
  31.  
  32. }
  33.  
  34. //Destructors
  35.  
  36. //Operators
  37. void operator=(const node &N){
  38. this->state = N.state;
  39. this->pre = N.pre;
  40. this->priority = N.priority;
  41. this->depth = N.depth;
  42. this->x = N.x;
  43. this->y = N.y;
  44. }
  45.  
  46. //Methods
  47. void getxy(){
  48. int i,j;
  49. for(i = 0 ; i < 3 ; i++)
  50. for(j = 0 ; j < 3 ; j++){
  51. if(this->state[i][j] == 0){
  52. this->x = i;
  53. this->y = j;
  54. return;
  55. }
  56. }
  57. }
  58.  
  59. bool CanMoveUp(); // (0)
  60. bool CanMoveDown(); // (1)
  61. bool CanMoveLeft(); // (2)
  62. bool CanMoveRight(); // (3)
  63. bool CanMove(int i);
  64.  
  65. node MoveUp();
  66. node MoveDown();
  67. node MoveLeft();
  68. node MoveRight();
  69. node Move(int i);
  70. };
  71.  
  72. bool node::CanMoveUp(){
  73. if(this->x == 0 || this->pre == 0)
  74. return false;
  75. return true;
  76. }
  77.  
  78. bool node::CanMoveDown(){
  79. if(this->x == 2 || this->pre == 1)
  80. return false;
  81. return true;
  82. }
  83.  
  84. bool node::CanMoveLeft(){
  85. if(this->y == 0 || this->pre == 2)
  86. return false;
  87. return true;
  88. }
  89.  
  90. bool node::CanMoveRight(){
  91. if(this->y == 2 || this->pre == 3)
  92. return false;
  93. return true;
  94. }
  95.  
  96. bool node::CanMove(int i){
  97. if(i==0) return this->CanMoveUp();
  98. if(i==1) return this->CanMoveDown();
  99. if(i==2) return this->CanMoveLeft();
  100. if(i==3) return this->CanMoveRight();
  101. }
  102.  
  103. node node::MoveUp(){
  104. node result;
  105. result.state = this->state;
  106. result.depth = this->depth + 1;
  107. result.pre = 1;
  108. result.x = this->x;
  109. result.y = this->y;
  110. swap(result.state[x][y],result.state[x-1][y]);
  111. result.x = this->x - 1;
  112. //Priority have to been updated after move
  113. return result;
  114. }
  115.  
  116. node node::MoveDown(){
  117. node result;
  118. result.state = this->state;
  119. result.depth = this->depth + 1;
  120. result.pre = 0;
  121. result.x = this->x;
  122. result.y = this->y;
  123. swap(result.state[x][y],result.state[x+1][y]);
  124. result.x = this->x + 1;
  125. //Priority have to been updated after move
  126. return result;
  127. }
  128.  
  129. node node::MoveLeft(){
  130. node result;
  131. result.state = this->state;
  132. result.depth = this->depth + 1;
  133. result.pre = 3;
  134. result.x = this->x;
  135. result.y = this->y;
  136. swap(result.state[x][y],result.state[x][y-1]);
  137. result.y = y - 1;
  138. //Priority have to been updated after move
  139. return result;
  140. }
  141.  
  142. node node::MoveRight(){
  143. node result;
  144. result.state = this->state;
  145. result.depth = this->depth + 1;
  146. result.pre = 2;
  147. result.x = this->x;
  148. result.y = this->y;
  149. swap(result.state[x][y],result.state[x][y+1]);
  150. result.y = y + 1;
  151. //Priority have to been updated after move
  152. return result;
  153. }
  154.  
  155. node node::Move(int i){
  156. if(i==0) return this->MoveUp();
  157. if(i==1) return this->MoveDown();
  158. if(i==2) return this->MoveLeft();
  159. if(i==3) return this->MoveRight();
  160. }
  161. //end methods
  162.  
  163. //used to compare 2 Node's priority to pussh them into priority_queue.
  164. struct cmp{
  165. bool operator()(node A, node B){
  166. if(A.priority == B.priority) return (A.depth > B.depth);
  167. return A.priority > B.priority;
  168. }
  169. };
  170.  
  171.  
  172. int* get_pos(int a, node des){
  173. int i,j;
  174. int *result = new int[2];
  175. for(i = 0 ; i < 3 ; i++){
  176. for(j = 0 ; j < 3 ; j++){
  177. if(des.state[i][j] == a)
  178. {
  179. result[0] = i;
  180. result[1] = j;
  181. return result;
  182. }
  183. }
  184. }
  185. }
  186.  
  187. //function to get priority (heuristic search)
  188. int get_priority(node current, node des){
  189. int i,j,result = 0;
  190. int *pos = new int[2];
  191. for(i = 0 ; i < 3 ; i++){
  192. for(j = 0 ; j < 3; j++){
  193. if(current.state[i][j] != 0){
  194. pos = get_pos(current.state[i][j],des);
  195. result += (pos[0]-i)*(pos[0]-i) + (pos[1]-j)*(pos[1]-j);
  196. }
  197. }
  198. }
  199. return result;
  200. }
  201.  
  202.  
  203.  
  204. int Find(node x, vector<node> seen){
  205. int i;
  206. for(i=0;i<seen.size();i++){
  207. if(x.state == seen[i].state) return seen[i].pre;
  208. }
  209. return -1;
  210. }
  211.  
  212.  
  213.  
  214. void Cout(vector<vector <int> > a){
  215. int i,j;
  216. cout<<endl;
  217. for(i=0 ; i<3; i++){
  218. for(j=0 ; j<3; j++)
  219. cout<<a[i][j]<<" ";
  220. cout<<endl;
  221. }
  222. }
  223.  
  224.  
  225. bool CanFind(node x, priority_queue <node,vector<node>,cmp> &q ){
  226. priority_queue <node,vector<node>,cmp> new_q;
  227. bool result=false;
  228. while(!q.empty()){
  229. node current = q.top();
  230. q.pop();
  231. if(x.state == current.state ){
  232. if(x.depth < current.depth)
  233. new_q.push(x);
  234. else new_q.push(current);
  235. result = true;
  236. }
  237. else new_q.push(current);
  238. }
  239. q = new_q;
  240. return result;
  241. }
  242.  
  243. bool CanFind_Seen(node x, vector<node> &seen,priority_queue <node,vector<node>,cmp> &pq ){
  244. int i;
  245. for(i = 0; i<seen.size() ;i++){
  246. if(x.state == seen[i].state){
  247. if(x.depth < seen[i].depth){
  248.  
  249. pq.push(x);
  250. seen.erase(seen.begin()+i);
  251. }//endif
  252. return true;
  253. }//endif
  254. }//endfor
  255. return false;
  256. }
  257.  
  258. bool CanFind_Seenv2(node x, vector<node> seen ){
  259. int i;
  260. for(i = 0; i<seen.size() ;i++){
  261. if(x.state == seen[i].state){
  262. return true;
  263. }//endif
  264. }//endfor
  265. return false;
  266. }
  267.  
  268. int get_total(node current, node des){
  269. int i,j,result = 0;
  270. for(i = 0 ; i < 3 ; i++){
  271. for(j = 0 ; j < 3 ; j++){
  272. if(current.state[i][j] != 0 && current.state[i][j]!= des.state[i][j])
  273. result++;
  274. }
  275. }
  276. return result;
  277. }
  278.  
  279. void go(node start, node des){
  280. priority_queue <node,vector<node>,cmp> pq;
  281. vector<node> seen;
  282. // store nodes which have been seen before.
  283. // Chứa các node đã xem qua
  284. int i,j,loop=0;
  285. bool inSeen,inPQ;
  286. node neightbor,temp,current;
  287. start.getxy();
  288. start.priority = get_priority(start,des);
  289. // get priority of start node.
  290. // tính độ ưu tiên cho node start.
  291. pq.push(start);
  292. //thêm start vào pq
  293. while(!pq.empty()){
  294. current = pq.top(); // xét node current có độ ưu tiên thấp nhất trong pq.
  295. pq.pop(); //loại bỏ nó khỏi pq.
  296. if (!CanFind_Seenv2(current,seen)){
  297. loop++;
  298. seen.push_back(current); //đánh dấu nó đã xem qua rồi.
  299. //Nếu current là đích dừng lại và in kết quả
  300. if (current.state == des.state) {
  301. temp = current; // biến này dùng để in kết quả
  302. break;
  303. }
  304. //Find the neghtbor nodes:
  305. //Tìm các node con của node current
  306. for(i=0;i<4;i++){
  307. if(current.CanMove(i)){
  308. // Với mỗi node con neighbor của current
  309. neightbor = current.Move(i);
  310. //Tình priority cho neighbor
  311. neightbor.priority = get_priority(neightbor,des) /*+get_total(neightbor,des)*/+ neightbor.depth;
  312. //cout<<"depth: "<<neightbor.depth<<" heu:"<<h<<" ";
  313. //Nếu chưa thấy trước đó, thêm nó vào pq
  314. //inSeen = CanFind_Seen(neightbor,seen,pq);
  315. //inPQ = CanFind(neightbor,pq);
  316. //if(!inSeen && !inPQ){
  317. pq.push(neightbor);
  318. //}
  319. }//endif
  320. }//endfor
  321. }
  322. }//endwhile
  323. //print the result
  324.  
  325. cout<<"steps:"<<temp.depth<<endl;
  326. vector<node> result;
  327. result.push_back(temp);
  328. temp = temp.Move(temp.pre);
  329. while(1){
  330. //Cout(temp.state);
  331. result.push_back(temp);
  332. int next = Find(temp,seen);
  333. if (next == -1) break;
  334. temp = temp.Move(next);
  335. }
  336. for(i=result.size()-1 ; i>=0 ; i--){
  337. Cout(result[i].state);
  338. //Sleep(1000);
  339. }
  340. cout<<"Loop:"<<loop<<endl;
  341. cout<<"steps:"<<result.size()-1<<endl;
  342.  
  343. }
  344.  
  345. int main()
  346. {
  347. clock_t t;
  348.  
  349. for(int t=0;t<100;t++){
  350.  
  351. node start, des;
  352. int i,j;
  353. //start.priority = get_priority(start,des) + start.depth ;
  354. for(i=0;i<3;i++)
  355. for(j=0;j<3;j++)
  356. cin>>start.state[i][j];
  357. for(i=0;i<3;i++)
  358. for(j=0;j<3;j++)
  359. cin>>des.state[i][j];
  360. t = clock();
  361. //cout<<get_priority(start,des);
  362. go(start,des);
  363. cout<<"done.";
  364. t = clock() - t;
  365. cout<<"Time: "<<((float)t)/CLOCKS_PER_SEC<<" s";
  366. cin>>i;
  367. }
  368. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement