A*算法的简单实现

A*算简单实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define ROW 5
#define COL 5

// 结点表示
typedef struct Node {
    int row, col;       // 结点在地图中的坐标
    int f, g, h;        // 用于计算路径的代价
    struct Node* parent; // 用于回溯路径
} Node;

Node* createNode(int row, int col) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->row = row;
    newNode->col = col;
    newNode->f = newNode->g = newNode->h = 0;
    newNode->parent = NULL;
    return newNode;
}

// 是否为有效结点
bool isValid(int row, int col) {
    return (row >= 0) && (row < ROW) && (col >= 0) && (col < COL);
}

// 是否为障碍物
bool isObstacle(int map[ROW][COL], int row, int col) {
    return map[row][col] == 1; // 1表示障碍物
}

// 是否为终点
bool isDestination(int row, int col, Node* dest) {
    return (row == dest->row) && (col == dest->col);
}

// 计算H值(启发函数,估计从当前结点到目标结点的代价)
int calculateHValue(int row, int col, Node* dest) {
    return abs(row - dest->row) + abs(col - dest->col);
}

// A*算法实现
void AStarSearch(int map[ROW][COL], Node* start, Node* dest) {
    // 待访问结点集合
    Node* openList[ROW * COL];
    int openListSize = 0;

    // 已访问结点集合
    bool closedList[ROW][COL];
    memset(closedList, false, sizeof(closedList));

    // 添加起点到待访问集合
    openList[openListSize++] = start;

    // 定义相邻结点的行列偏移
    int rowOffset[] = {-1, 0, 1, 0};
    int colOffset[] = {0, 1, 0, -1};

    while (openListSize > 0) {
        // 从待访问集合中选择f值最小的结点
        int currentIndex = 0;
        for (int i = 1; i < openListSize; ++i) {
            if (openList[i]->f < openList[currentIndex]->f) {
                currentIndex = i;
            }
        }

        // 当前结点
        Node* current = openList[currentIndex];

        // 从待访问集合中移除当前结点
        openList[currentIndex] = openList[openListSize - 1];
        --openListSize;

        // 将当前结点标记为已访问
        closedList[current->row][current->col] = true;

        // 遍历当前结点的相邻结点
        for (int i = 0; i < 4; ++i) {
            int newRow = current->row + rowOffset[i];
            int newCol = current->col + colOffset[i];

            // 检查相邻结点是否为有效结点
            if (isValid(newRow, newCol)) {
                // 如果相邻结点是目标结点,结束搜索
                if (isDestination(newRow, newCol, dest)) {
                    dest->parent = current;
                    return;
                }

                // 如果相邻结点不是障碍物且未被访问过
                if (!closedList[newRow][newCol] && !isObstacle(map, newRow, newCol)) {
                    Node* adjacentNode = createNode(newRow, newCol);
                    adjacentNode->g = current->g + 1;
                    adjacentNode->h = calculateHValue(newRow, newCol, dest);
                    adjacentNode->f = adjacentNode->g + adjacentNode->h;
                    adjacentNode->parent = current;

                    // 如果相邻结点不在待访问集合中,将其添加进去
                    bool inOpenList = false;
                    for (int j = 0; j < openListSize; ++j) {
                        if (openList[j]->row == adjacentNode->row && openList[j]->col == adjacentNode->col) {
                            inOpenList = true;
                            break;
                        }
                    }

                    if (!inOpenList) {
                        openList[openListSize++] = adjacentNode;
                    }
                }
            }
       

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A*算法是一种常用的启发式搜索算法,用于在图形或网络中找到最短路径。它使用估价函数来评估每个节点的优先级,并选择具有最低总代价的节点进行扩展。在实现A*算法时,需要定义一个启发式函数来估计从当前节点到目标节点的代价。常见的启发式函数包括曼哈顿距离、欧几里得距离等。 在Matlab中实现A*算法,可以按照以下步骤进行: 1. 定义地图和起点、终点坐标。 2. 定义启发式函数,例如曼哈顿距离。 3. 定义节点类,包括节点坐标、代价、父节点等信息。 4. 初始化起点节点,并将其加入开放列表。 5. 进入循环,直到开放列表为空或者找到终点节点: a. 从开放列表中选择代价最小的节点进行扩展。 b. 对于每个相邻节点,计算其代价和启发式函数值,并更新其父节点和总代价。 c. 将相邻节点加入开放列表或者更新开放列表中已有的节点。 6. 如果找到终点节点,则回溯路径并输出结果。 下面是一个简单的A*算法Matlab实现示例: ```matlab % 定义地图和起点、终点坐标 map = [0 0 0 0 0; 0 1 1 0 0; 0 1 0 0 0; 0 1 1 1 0; 0 0 0 0 0]; start = [1,1]; goal = [5,5]; % 定义启发式函数 heuristic = @(pos) abs(pos(1)-goal(1)) + abs(pos(2)-goal(2)); % 定义节点类 classdef Node properties pos cost parent end methods function obj = Node(pos, cost, parent) obj.pos = pos; obj.cost = cost; obj.parent = parent; end function priority = getPriority(obj) priority = obj.cost + heuristic(obj.pos); end end end % 初始化起点节点,并将其加入开放列表 startNode = Node(start, 0, []); openList = [startNode]; % 进入循环,直到开放列表为空或者找到终点节点 while ~isempty(openList) % 从开放列表中选择代价最小的节点进行扩展 [~, idx] = min(arrayfun(@(x) x.getPriority(), openList)); currentNode = openList(idx); openList(idx) = []; % 如果找到终点节点,则回溯路径并输出结果 if isequal(currentNode.pos, goal) path = currentNode.pos; while ~isempty(currentNode.parent) currentNode = currentNode.parent; path = [currentNode.pos; path]; end disp(path); break; end % 对于每个相邻节点,计算其代价和启发式函数值,并更新其父节点和总代价 neighbors = getNeighbors(currentNode.pos, map); for i = 1:size(neighbors, 1) neighborNode = Node(neighbors(i,:), currentNode.cost+1, currentNode); % 将相邻节点加入开放列表或者更新开放列表中已有的节点 idx = find(arrayfun(@(x) isequal(x.pos, neighborNode.pos), openList)); if isempty(idx) openList = [openList; neighborNode]; else if neighborNode.cost < openList(idx).cost openList(idx) = neighborNode; end end end end function neighbors = getNeighbors(pos, map) [m, n] = size(map); neighbors = []; if pos(1) > 1 && map(pos(1)-1,pos(2)) == 0 neighbors = [neighbors; pos-[1,0]]; end if pos(1) < m && map(pos(1)+1,pos(2)) == 0 neighbors = [neighbors; pos+[1,0]]; end if pos(2) > 1 && map(pos(1),pos(2)-1) == 0 neighbors = [neighbors; pos-[0,1]]; end if pos(2) < n && map(pos(1),pos(2)+1) == 0 neighbors = [neighbors; pos+[0,1]]; end end ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值