美文网首页
2.A* Search

2.A* Search

作者: 徐凯_xp | 来源:发表于2020-02-03 20:34 被阅读0次

    A *伪代码

    Search( grid, initial_point, goal_point ) :

    1.初始化一个空的打开节点列表
    2.使用以下内容初始化起始节点:

    • initial_point给出的x和y值
    • g = 0,其中g是每一步的成本
    • h由启发函数(当前坐标和目标的函数)给出
    1. 将新节点添加到打开的节点列表中
    2. while 打开节点的列表是非空的:
    • 按f值对打开的列表进行排序
    • 弹出最佳单元格(称为current单元格)。
    • 在路径中将单元格的坐标标记在网格中。
    • if current单元格是goal单元格:
      • 返回单元格
    • else将搜索范围扩展到current节点的邻居。这包括以下步骤:
      • 检查网格中的每个相邻单元,以确保该单元为空:它尚未关闭且没有障碍。
      • 如果单元格为空,请计算成本(g值)和启发式方法,然后将其添加到打开的节点列表中
      • 将单元格标记为关闭。
    1. 如果由于打开的节点列表为空而退出while循环,则表明您用完了新节点以进行探索,但未找到路径。
    #include <algorithm>  // for sort
    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    using std::cout;
    using std::ifstream;
    using std::istringstream;
    using std::sort;
    using std::string;
    using std::vector;
    using std::abs;
    
    // State classes
    enum class State { kEmpty, kObstacle, kClosed, kPath, kStart, kFinish };
    
    // Directional deltas
    const int delta[4][2]{ {-1, 0}, {0, -1}, {1, 0}, {0, 1} };
    
    
    vector<State> ParseLine(string line) {
        istringstream sline(line);
        int n;
        char c;
        vector<State> row;
        while (sline >> n >> c && c == ',') {
            if (n == 0) {
                row.push_back(State::kEmpty);
            }
            else {
                row.push_back(State::kObstacle);
            }
        }
        return row;
    }
    
    
    vector<vector<State>> ReadBoardFile(string path) {
        ifstream myfile(path);
        vector<vector<State>> board{};
        if (myfile) {
            string line;
            while (getline(myfile, line)) {
                vector<State> row = ParseLine(line);
                board.push_back(row);
            }
        }
        return board;
    }
    
    
    /**
     * Compare the F values of two cells.
     */
    bool Compare(const vector<int> a, const vector<int> b) {
        int f1 = a[2] + a[3]; // f1 = g1 + h1
        int f2 = b[2] + b[3]; // f2 = g2 + h2
        return f1 > f2;
    }
    
    
    /**
     * Sort the two-dimensional vector of ints in descending order.
     */
    void CellSort(vector<vector<int>>* v) {
        sort(v->begin(), v->end(), Compare);
    }
    
    
    // Calculate the manhattan distance
    int Heuristic(int x1, int y1, int x2, int y2) {
        return abs(x2 - x1) + abs(y2 - y1);
    }
    
    
    /**
     * Check that a cell is valid: on the grid, not an obstacle, and clear.
     */
    bool CheckValidCell(int x, int y, vector<vector<State>>& grid) {
        bool on_grid_x = (x >= 0 && x < grid.size());
        bool on_grid_y = (y >= 0 && y < grid[0].size());
        if (on_grid_x && on_grid_y)
            return grid[x][y] == State::kEmpty;
        return false;
    }
    
    
    /**
     * Add a node to the open list and mark it as open.
     */
    void AddToOpen(int x, int y, int g, int h, vector<vector<int>>& openlist, vector<vector<State>>& grid) {
        // Add node to open vector, and mark grid cell as closed.
        openlist.push_back(vector<int>{x, y, g, h});
        grid[x][y] = State::kClosed;
    }
    
    
    /**
     * Expand current nodes's neighbors and add them to the open list.
     */
    void ExpandNeighbors(const vector<int>& current, int goal[2], vector<vector<int>>& openlist, vector<vector<State>>& grid) {
        // Get current node's data.
        int x = current[0];
        int y = current[1];
        int g = current[2];
    
        // Loop through current node's potential neighbors.
        for (int i = 0; i < 4; i++) {
            int x2 = x + delta[i][0];
            int y2 = y + delta[i][1];
    
            // Check that the potential neighbor's x2 and y2 values are on the grid and not closed.
            if (CheckValidCell(x2, y2, grid)) {
                // Increment g value and add neighbor to open list.
                int g2 = g + 1;
                int h2 = Heuristic(x2, y2, goal[0], goal[1]);
                AddToOpen(x2, y2, g2, h2, openlist, grid);
            }
        }
    }
    
    
    /**
     * Implementation of A* search algorithm
     */
    vector<vector<State>> Search(vector<vector<State>> grid, int init[2], int goal[2]) {
        // Create the vector of open nodes.
        vector<vector<int>> open{};
    
        // Initialize the starting node.
        int x = init[0];
        int y = init[1];
        int g = 0;
        int h = Heuristic(x, y, goal[0], goal[1]);
        AddToOpen(x, y, g, h, open, grid);
    
        while (open.size() > 0) {
            // Get the next node
            CellSort(&open);
            auto current = open.back();
            open.pop_back();
            x = current[0];
            y = current[1];
            grid[x][y] = State::kPath;
    
            // Check if we're done.
            if (x == goal[0] && y == goal[1]) {
                grid[init[0]][init[1]] = State::kStart;
                grid[goal[0]][goal[1]] = State::kFinish;
                return grid;
            }
    
            // If we're not done, expand search to current node's neighbors.
            ExpandNeighbors(current, goal, open, grid);
        }
    
        // We've run out of new nodes to explore and haven't found a path.
        cout << "No path found!" << "\n";
        return std::vector<vector<State>>{};
    }
    
    
    string CellString(State cell) {
        switch (cell) {
        case State::kObstacle: return "山     ";
        case State::kPath: return     "路径   ";
        case State::kStart: return    "起点   ";
        case State::kFinish: return   "终点   ";
        default: return               "0      ";
        }
    }
    
    
    void PrintBoard(const vector<vector<State>> board) {
        for (int i = 0; i < board.size(); i++) {
            for (int j = 0; j < board[i].size(); j++) {
                cout << CellString(board[i][j]);
            }
            cout << "\n";
        }
    }
    
    //#include "test.cpp"
    
    int main() {
        int init[2]{ 0, 0 };
        int goal[2]{ 4, 5 };
        auto board = ReadBoardFile("1.board");
        auto solution = Search(board, init, goal);
        PrintBoard(solution);
        system("pause");
        // Tests
       /* TestHeuristic();
        TestAddToOpen();
        TestCompare();
        TestSearch();
        TestCheckValidCell();
        TestExpandNeighbors();*/
    }
    

    相关文章

      网友评论

          本文标题:2.A* Search

          本文链接:https://www.haomeiwen.com/subject/pighxhtx.html