tBane Temat założony przez niniejszego użytkownika |
Algorytm szukania drogi » 2023-11-25 18:47:15 Cześć, poszukuje algorytmu, który znajdzie drogę z punktu (x1, y1) do punktu (x2, y2). Załóżmy, że mapa jest kafelkowa prosta, jak poniżej i z każdego pola można dojść do każdego pola.
(0,4)__(1,4)__(2,4)__(3,4)__(4,4)__(5,4) (0,3)__(1,3)__(2,3)__(3,3)__(4,3)__(5,3) (0,2)__(1,2)__(2,2)__(3,2)__(4,2)__(5,2) (0,1)__(1,1)__(2,1)__(3,1)__(4,1)__(5,1) (0,0)__(1,0)__(2,0)__(3,0)__(4,0)__(5,0)
Jeżeli jest taka możliwość poproszę o przykład użycia algorytmu. |
|
DejaVu |
» 2023-11-25 19:12:41 |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-11-25 19:14:08 Właśnie czytam od paru dni, i trudno mi to sobie wyobrazić. Dlatego poprosiłem o przykład użycia na prostej mapie.
Poza tym, ten algorytm jest zbyt złożony. Nie rozumiem po co używać koszt przejścia kafelka skoro to prosta mapa. Nie rozumiem o co chodzi z tą heurestyką. Poza tym ten algorytm nie działa... |
|
DejaVu |
» 2023-11-25 20:03:40 Ten kod działa i ma rysowanie mapki po każdym kroku. #include <iostream> #include <vector> #include <queue> #include <unordered_map> #include <algorithm>
struct Point { int x, y; Point() : x( 0 ) , y( 0 ) { } Point( int x, int y ) : x( x ) , y( y ) { } bool operator ==( const Point & other ) const { return x == other.x && y == other.y; } bool operator !=( const Point & other ) const { return x != other.x || y != other.y; } bool operator <( const Point & other ) const { return std::tie( x, y ) < std::tie( other.x, other.y ); } };
namespace std { template < > struct hash < Point > { size_t operator()( const Point & p ) const { return hash < int >()( p.x ) ^ hash < int >()( p.y ); } }; }
int heuristic( const Point & a, const Point & b ) { return abs( a.x - b.x ) + abs( a.y - b.y ); }
std::vector < Point > getNeighbors( const Point & p, const std::vector < std::vector < bool >> & map ) { std::vector < Point > neighbors; int dx[ 4 ] = { 1, 0, - 1, 0 }; int dy[ 4 ] = { 0, 1, 0, - 1 }; for( int i = 0; i < 4; ++i ) { int nx = p.x + dx[ i ], ny = p.y + dy[ i ]; if( nx >= 0 && nx < map.size() && ny >= 0 && ny < map[ 0 ].size() && map[ nx ][ ny ] ) { neighbors.emplace_back( nx, ny ); } } return neighbors; }
std::vector < Point > aStar( const std::vector < std::vector < bool >> & map, const Point & start, const Point & goal ) { std::priority_queue < std::pair < int, Point >, std::vector < std::pair < int, Point >>, std::greater < >> openSet; std::unordered_map < Point, Point > cameFrom; std::unordered_map < Point, int > costSoFar; openSet.emplace( 0, start ); cameFrom[ start ] = start; costSoFar[ start ] = 0; while( !openSet.empty() ) { Point current = openSet.top().second; openSet.pop(); if( current == goal ) { std::vector < Point > path; while( current != start ) { path.push_back( current ); current = cameFrom[ current ]; } path.push_back( start ); std::reverse( path.begin(), path.end() ); return path; } for( const Point & next: getNeighbors( current, map ) ) { int newCost = costSoFar[ current ] + 1; if( costSoFar.find( next ) == costSoFar.end() || newCost < costSoFar[ next ] ) { costSoFar[ next ] = newCost; int priority = newCost + heuristic( next, goal ); openSet.emplace( priority, next ); cameFrom[ next ] = current; } } } return { }; }
void drawMap( const std::vector < std::vector < bool >> & map, const Point & playerPos ) { std::cout << "=============\n"; int x = 0; for( const auto & row: map ) { int y = 0; for( const auto & cell: row ) { if( playerPos.x == x && playerPos.y == y ) std::cout << "* "; else std::cout <<( cell ? "_ ": "X " ); ++y; } std::cout << "\n"; x++; } std::cout << "\n"; }
int main() { std::vector < std::vector < bool >> map = { { true, true, true, false }, { false, true, false, true }, { true, true, true, true } }; Point start( 0, 0 ); Point goal( 2, 3 ); std::vector < Point > path = aStar( map, start, goal ); for( const auto & row: map ) { for( const auto & cell: row ) std::cout <<( cell ? "_ " : "X " ); std::cout << "\n"; } std::cout << "Path: "; for( const Point & p: path ) std::cout << "(" << p.x << ", " << p.y << ") "; std::cout << "\n"; for( const Point & p: path ) drawMap( map, p ); return 0; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-11-26 13:17:01 Ok, dziękuję. Teraz pozostało mi kod zrozumieć. Co oznacza ten fragment kodu namespace std { template < > struct hash < Point > { size_t operator()( const Point & p ) const { return hash < int >()( p.x ) ^ hash < int >()( p.y ); } }; }
|
|
pekfos |
» 2023-11-26 16:13:38 Specjalizacja std::hash<> dla Point. Funkcja hashująca potrzebna by można było używać Point jako klucza w tablicy hashującej std::unordered_map. |
|
« 1 » |