Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <queue>
  4. #include <string>
  5. #include <math.h>
  6. #include <ctime>
  7. #include <cstdlib>
  8. #include <cstdio>
  9. using namespace std;
  10.  
  11. const int n = 10; // horizontal size of the map
  12. const int m = 10; // vertical size size of the map
  13. static int map[n][m];
  14. static int closed_nodes_map[n][m]; // map of closed (tried-out) nodes
  15. static int open_nodes_map[n][m]; // map of open (not-yet-tried) nodes
  16. static int dir_map[n][m]; // map of directions
  17. const int dir = 4; // number of possible directions to go at any position
  18. static int dx[dir] = { 1 , 0 , -1 , 0 };
  19. static int dy[dir] = { 0 , 1 , 0 , -1 };
  20.  
  21. class node
  22. {
  23.     int xPos , yPos; // current position
  24.     int level; // total distance already travelled to reach the node
  25.     // priority=level+remaining distance estimate
  26.     int priority;  // smaller: higher priority
  27.  
  28.     public:
  29.         node( int xp , int yp , int d , int p )
  30.             { xPos = xp ; yPos = yp ; level = d ; priority = p ; }
  31.  
  32.         int getxPos() const { return xPos; }
  33.         int getyPos() const { return yPos; }
  34.         int getLevel() const { return level; }
  35.         int getPriority() const { return priority; }
  36.  
  37.         void updatePriority( const int & xDest , const int & yDest )
  38.         {
  39.              priority = level + estimate( xDest , yDest ) * 10; //A*
  40.         }
  41.         void nextLevel( const int & i ) // i: direction
  42.         {
  43.              level += 10;
  44.         }
  45.         // Estimation function for the remaining distance to the goal.
  46.         const int & estimate( const int & xDest , const int & yDest ) const
  47.         {
  48.             static int xd , yd , d;
  49.             xd = xDest - xPos;
  50.             yd = yDest - yPos;
  51.             // Manhattan distance
  52.             d = abs( xd ) + abs( yd );
  53.             return( d );
  54.         }
  55. };
  56.  
  57. bool operator<( const node & a , const node & b ) // Determine priority (in the priority queue)
  58. {
  59.     return a.getPriority() > b.getPriority();
  60. }
  61.  
  62. string pathFind( const int & xStart , const int & yStart , const int & xFinish , const int & yFinish ) /// A* , ruta e un string
  63. {
  64.     static priority_queue< node > pq[2]; // list of open (not-yet-tried) nodes
  65.     static int pqi; // pq index
  66.     static node* n0;
  67.     static node* m0;
  68.     static int i , j , x , y , xdx , ydy;
  69.     static char c;
  70.     pqi = 0;
  71.     // reset the node maps
  72.     for( y = 0 ; y < m ; ++y )
  73.         for( x = 0 ; x < n ; ++x )
  74.         {
  75.             closed_nodes_map[x][y] = 0;
  76.             open_nodes_map[x][y] = 0;
  77.         }
  78.  
  79.     // create the start node and push into list of open nodes
  80.     n0 = new node( xStart , yStart , 0 , 0 );
  81.     n0 -> updatePriority( xFinish , yFinish );
  82.     pq[pqi].push( *n0 );
  83.     open_nodes_map[x][y] = n0 -> getPriority(); // mark it on the open nodes map
  84.  
  85.     // A* search
  86.     while( !pq[pqi].empty() )
  87.     {
  88.         // get the current node w/ the highest priority
  89.         // from the list of open nodes
  90.         n0 = new node( pq[pqi].top().getxPos() , pq[pqi].top().getyPos() , pq[pqi].top().getLevel() , pq[pqi].top().getPriority() );
  91.  
  92.         x = n0 -> getxPos(); y = n0 -> getyPos();
  93.  
  94.         pq[pqi].pop(); // remove the node from the open list
  95.         open_nodes_map[x][y] = 0;
  96.         // mark it on the closed nodes map
  97.         closed_nodes_map[x][y] = 1;
  98.  
  99.         // quit searching when the goal state is reached
  100.         //if((*n0).estimate(xFinish, yFinish) == 0)
  101.         if( x == xFinish && y == yFinish )
  102.         {
  103.             // generate the path from finish to start
  104.             // by following the directions
  105.             string path = "";
  106.             while( !( x == xStart && y == yStart ) )
  107.             {
  108.                 j = dir_map[x][y];
  109.                 c = '0' + ( j + dir / 2 ) % dir;
  110.                 path = c + path;
  111.                 x += dx[j];
  112.                 y += dy[j];
  113.             }
  114.             delete n0; // garbage collection
  115.             // empty the leftover nodes
  116.             while( !pq[pqi].empty() ) pq[pqi].pop();
  117.             return path;
  118.         }
  119.  
  120.         // generate moves (child nodes) in all possible directions
  121.         for( i = 0 ; i < dir ; ++i )
  122.         {
  123.             xdx = x + dx[i]; ydy = y + dy[i];
  124.             if( !( xdx < 0 || xdx > n - 1 || ydy < 0 || ydy > m - 1 || map[xdx][ydy] == 1 || closed_nodes_map[xdx][ydy] == 1 ) )
  125.             {
  126.                 // generate a child node
  127.                 m0 = new node( xdx , ydy , n0 -> getLevel() , n0 -> getPriority() );
  128.                 m0 -> nextLevel( i );
  129.                 m0 -> updatePriority( xFinish , yFinish );
  130.  
  131.                 // if it is not in the open list then add into that
  132.                 if( open_nodes_map[xdx][ydy] == 0 )
  133.                 {
  134.                     open_nodes_map[xdx][ydy] = m0 -> getPriority();
  135.                     pq[pqi].push( *m0 );
  136.                     // mark its parent node direction
  137.                     dir_map[xdx][ydy] = ( i + dir / 2 ) % dir;
  138.                 }
  139.                 else if( open_nodes_map[xdx][ydy] > m0 -> getPriority() )
  140.                 {
  141.                     // update the priority info
  142.                     open_nodes_map[xdx][ydy] = m0 -> getPriority();
  143.                     // update the parent direction info
  144.                     dir_map[xdx][ydy] = ( i + dir / 2 ) % dir;
  145.                     // replace the node
  146.                     // by emptying one pq to the other one
  147.                     // except the node to be replaced will be ignored
  148.                     // and the new node will be pushed in instead
  149.                     while( !(pq[pqi].top().getxPos() == xdx && pq[pqi].top().getyPos() == ydy ) )
  150.                     {
  151.                         pq[1-pqi].push( pq[pqi].top() );
  152.                         pq[pqi].pop();
  153.                     }
  154.                     pq[pqi].pop(); // remove the wanted node
  155.  
  156.                     // empty the larger size pq to the smaller one
  157.                     if( pq[pqi].size() > pq[1-pqi].size() ) pqi = 1 - pqi;
  158.                     while( !pq[pqi].empty() )
  159.                     {
  160.                         pq[1-pqi].push( pq[pqi].top() );
  161.                         pq[pqi].pop();
  162.                     }
  163.                     pqi = 1 - pqi;
  164.                     pq[pqi].push( *m0 ); // add the better node instead
  165.                 }
  166.                 else delete m0; // garbage collection
  167.             }
  168.         }
  169.         delete n0; // garbage collection
  170.     }
  171.     return ""; // no route found
  172. }
  173.  
  174. void Afisare()
  175. {
  176.     // display the map with the route
  177.     for( int y = 0 ; y < m ; ++y )
  178.     {
  179.         for( int x = 0 ; x < n ; ++x )
  180.             if( map[x][y] == 0 )
  181.                 cout << ".";
  182.             else if( map[x][y] == 1 )
  183.                 cout << "O"; //obstacle
  184.             else if( map[x][y] == 2 )
  185.                 cout << "S"; //start
  186.             else if( map[x][y] == 3 )
  187.                 cout << "R"; //route
  188.             else if( map[x][y] == 4 )
  189.                 cout << "F"; //finish
  190.         cout << '\n';
  191.     }
  192. }
  193.  
  194. void CreeazaHarta()
  195. {
  196.     // creeaza o matrice goala
  197.     for ( int y = 0 ; y < m ; ++y )
  198.         for ( int x = 0 ; x < n ; ++x )
  199.             map[x][y] = 0;
  200.     // umple matricea cu un model de '+'
  201.     for ( int x = n / 8 ; x < n * 7 / 8 ; ++x )
  202.         map[x][m/2] = 1;
  203.     for ( int y = m / 8 ; y < m * 7 / 8 ; ++y )
  204.         map[n / 2][y] = 1;
  205. }
  206.  
  207. int main()
  208. {
  209.     CreeazaHarta();
  210.     srand( time( NULL ) );
  211.     // alege la intamplare locul de start si destinatia
  212.     int xA , yA , xB , yB;
  213.     switch( rand() % 8 )
  214.     {
  215.         case 0 : xA = 0 ; yA = 0 ; xB = n - 1 ; yB = m - 1 ; break;
  216.         case 1 : xA = 0 ; yA = m - 1 ; xB = n - 1 ; yB = 0 ; break;
  217.         case 2 : xA = n / 2 - 1 ; yA = m / 2 - 1 ; xB = n / 2 + 1 ; yB = m / 2 + 1 ; break;
  218.         case 3 : xA = n / 2 - 1 ; yA = m / 2 + 1 ; xB = n / 2 + 1 ; yB = m / 2 - 1 ; break;
  219.         case 4 : xA = n / 2 - 1 ; yA = 0 ; xB = n / 2 + 1 ; yB = m - 1 ; break;
  220.         case 5 : xA = n / 2 + 1 ; yA = m - 1 ; xB = n / 2 - 1 ; yB = 0 ; break;
  221.         case 6 : xA = 0 ; yA = m / 2 - 1 ; xB = n - 1 ; yB = m / 2 + 1 ; break;
  222.         case 7 : xA = n - 1 ; yA = m / 2 + 1 ; xB = 0 ; yB = m / 2 - 1 ; break;
  223.     }
  224.     cout<<"Map Size (X,Y): "<<n<<","<<m<<endl;
  225.     cout<<"Start: "<<xA<<","<<yA<<endl;
  226.     cout<<"Finish: "<<xB<<","<<yB<<endl;
  227.     // get the route
  228.     clock_t start = clock();
  229.     string route=pathFind(xA, yA, xB, yB);
  230.     if( route=="" ) cout<<"An empty route generated!"<<endl;
  231.     clock_t end = clock();
  232.     double time_elapsed = double(end - start);
  233.     cout<<"Time to calculate the route (ms): "<<time_elapsed<<endl;
  234.     cout<<"Route:"<<endl;
  235.     cout<<route<<endl<<endl;
  236.  
  237.     // follow the route on the map and display it
  238.     if( route.length() > 0 )
  239.     {
  240.         int j; char c;
  241.         int x = xA , y = yA;
  242.         map[x][y] = 2;
  243.         for( int i = 0 ; i < route.length() ; ++i )
  244.         {
  245.             c = route.at(i);
  246.             j = c - '0';
  247.             x = x + dx[j];
  248.             y = y + dy[j];
  249.             map[x][y] = 3;
  250.         }
  251.         map[x][y] = 4;
  252.         Afisare(); /// Arata ruta
  253.     }
  254.     return 0;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement