A星寻路算法简易版(代码实现)

在这里插入图片描述

绿色为起点,红色为终点,蓝色为墙不可走。启动只能上下左右不可以斜着走。

以下为A*寻路算法代码实现,核心思想就是只走F值(格子评估值)最小的格子,直至到达终点。

F值最小代表着从起点出发到达终点需要的最少的步数,只走最少的步数,那么路径就是最短的。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <memory>
#include<stdio.h>
#include<string.h>
#include <cassert>
#include <cmath>
using namespace std;

typedef struct _node
{
    int x;//地图中的第几行
    int y;//地图中的第几列
    int F;//评估值F=G+H,G代表从起点到当前格子的成本,H代表从当前格无视障碍到目标的成本
    //尽量选择步数少的也就是F值小的
    int G;//G代表从起点到当前格子的成本,也就是走了多少步
    int H;//H代表从当前格无视障碍到目标的成本,也就是至少还需要多少步
    struct _node* preNode;//父节点
}node;



vector<node*> openList;//储存可到达或可走的格子
vector<node*> closeList;//储存已经到达或者已经走过的格子
int map[5][7]{
    //5行7列
    // 0  1  2  3  4  5  6
    0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 0, 0, 0,
};
//node map[1][2]{{{0,0,0,0,0}},{{0,0,0,0,0}}};

//找出OpenList中F值最小的方格
int findMinNode()
{
    int index = 0;
    int size = openList.size();
    for(int i=1;i<size;++i)
    {
        if(openList[i]->F < openList[index]->F)
        {
            index = i;
        }
    }
    return index;
}

void findNeighbors(node* current,node* end)
{
    int openSize = openList.size();
    int closeSize = closeList.size();
    bool isInclude = false;
    //上
    if(current->x-1>=0 &&map[current->x-1][current->y]==0 )
    {
        for(int i =0;i<openSize;++i)
        {
            if(openList[i]->x == current->x-1 && openList[i]->y == current->y)
            {
                isInclude = true;
                break;
            }
        }
        for(int i =0;i<closeSize;++i)
        {
            if(closeList[i]->x == current->x-1 && closeList[i]->y == current->y)
            {
                isInclude = true;
                break;
            }
        }
        if(isInclude == false)
        {
            node *up = (node*)new node;
            up->x = current->x-1;
            up->y = current->y;
            cout<<"up  "<<up->x<<"  "<<up->y<<endl;
            up->G = current->G+1;
            up->H = abs(end->x-up->x)+abs(end->y-up->y);
            up->preNode = current;
            openList.push_back(up);
        }
    }
    //下
    isInclude = false;
    if(current->x+1<5 &&map[current->x+1][current->y]==0 )
    {
        for(int i =0;i<openSize;++i)
        {
            if(openList[i]->x == current->x+1 && openList[i]->y == current->y)
            {
                isInclude = true;
                break;
            }
        }
        for(int i =0;i<closeSize;++i)
        {
            if(closeList[i]->x == current->x+1 && closeList[i]->y == current->y)
            {
                isInclude = true;
                break;
            }
        }
        if(isInclude == false)
        {
            node* down=(node*)new node;
            down->x = current->x+1;
            down->y = current->y;
            cout<<"down  "<<down->x<<"  "<<down->y<<endl;
            down->G = current->G+1;
            down->H = abs(end->x-down->x)+abs(end->y-down->y);
            down->preNode = current;
            openList.push_back(down);
        }
    }
    //左
    isInclude = false;
    if(current->y-1>=0 &&map[current->x][current->y-1]==0)
    {
        for(int i =0;i<openSize;++i)
        {
            if(openList[i]->x == current->x && openList[i]->y == current->y-1)
            {
                isInclude = true;
                break;
            }
        }
        for(int i =0;i<closeSize;++i)
        {
            if(closeList[i]->x == current->x && closeList[i]->y == current->y-1)
            {
                isInclude = true;
                break;
            }
        }
        if(isInclude == false)
        {
            node* left=(node*)new node;
            left->x = current->x;
            left->y = current->y-1;
            cout<<"left  "<<left->x<<"  "<<left->y<<endl;
            left->G = current->G+1;
            left->H = abs(end->x-left->x)+abs(end->y-left->y);
            left->preNode = current;
            openList.push_back(left);
        }
    }
    //右
    isInclude = false;
    if(current->y+1<7 &&map[current->x][current->y+1]==0)
    {
        for(int i =0;i<openSize;++i)
        {
            if(openList[i]->x == current->x && openList[i]->y == current->y+1)
            {
                isInclude = true;
                break;
            }
        }
        for(int i =0;i<closeSize;++i)
        {
            if(closeList[i]->x == current->x && closeList[i]->y == current->y+1)
            {
                isInclude = true;
                break;
            }
        }
        if(isInclude == false)
        {
            node* right=(node*)new node;
            right->x = current->x;

            right->y = current->y+1;
            cout<<"right  "<<right->x<<"  "<<right->y<<endl;
            right->G = current->G+1;
            right->H = abs(end->x-right->x)+abs(end->y-right->y);
            right->preNode = current;
            openList.push_back(right);
        }
    }
}

void AstarSerch (node* start,node* end)
{
    openList.push_back(start);
    while(openList.size()>0)
    {
        int currentIndex = findMinNode();//找出OpenList中F值最小的方格,并把该格移出OpenList,放入CloseList。代表这个格子已到达并检查过了。
        node* current = openList[currentIndex];
        openList.erase(openList.begin()+currentIndex);
        closeList.push_back(current);
        findNeighbors(current,end);//找出当前格上下左右所有可到达的格子,看它们是否在OpenList当中。计算出相应的G、H、F值,并把当前格子作为它们的“父亲节点”。
        for(int i =0;i<openList.size();++i)
        {
            if(openList[i]->x == end->x && openList[i]->y == end->y)
            {
                cout<<"find it"<<endl;
                node* cur = openList[i];
                while(cur->preNode)
                {
                    cout<<""<<cur->x<<"   "<<cur->y<<endl;
                    cur=(cur->preNode);
                }
                return;
            }
        }
    }
}

int main()
{
    node* start=(node*)new node;
    start->x=2;
    start->y=1;
    start->F=0;
    start->G=0;
    start->H=0;
    start->preNode = nullptr;

    node* end=(node*)new node;
    end->x=2;
    end->y=5;
    end->F=0;
    end->G=0;
    end->H=0;

    AstarSerch(start,end);

    return 0;
}

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python代码实现A寻路算法可以使用以下代码:def astar(start, goal): closedset = set() openset = set([start]) came_from = {} gscore = {start: 0} fscore = {start: heuristic_cost_estimate(start, goal)} while openset: current = min(openset, key=fscore.get) if current == goal: return reconstruct_path(came_from, current) openset.remove(current) closedset.add(current) for neighbor in get_neighbors(current): if neighbor in closedset: continue tentative_gscore = gscore[current] + dist_between(current, neighbor) if neighbor not in openset: openset.add(neighbor) elif tentative_gscore >= gscore[neighbor]: continue came_from[neighbor] = current gscore[neighbor] = tentative_gscore fscore[neighbor] = gscore[neighbor] + heuristic_cost_estimate(neighbor, goal) return False ### 回答2: A寻路算法是一种常用的路径规划算法,可以在给定的地图中找到最短路径。下面是用Python实现A寻路算法代码示例: ```python import heapq # 定义节点类 class Node: def __init__(self, row, col, g, h): self.row = row self.col = col self.g = g self.h = h def __lt__(self, other): return self.g + self.h < other.g + other.h # 计算启发式代价(h值) def heuristic(row, col, target_row, target_col): return abs(target_row - row) + abs(target_col - col) # A寻路算法 def astar_search(start, target, grid): directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 上下左右四个方向 rows, cols = len(grid), len(grid[0]) visited = set() # 已访问的节点集合 pq = [] # 优先队列,用来选择下一个节点 heapq.heappush(pq, start) while pq: curr_node = heapq.heappop(pq) row, col = curr_node.row, curr_node.col visited.add((row, col)) if row == target.row and col == target.col: return curr_node.g for d in directions: new_row, new_col = row + d[0], col + d[1] if 0 <= new_row < rows and 0 <= new_col < cols and grid[new_row][new_col] != 1: new_g = curr_node.g + 1 new_h = heuristic(new_row, new_col, target.row, target.col) new_node = Node(new_row, new_col, new_g, new_h) if (new_row, new_col) not in visited: heapq.heappush(pq, new_node) return -1 # 示例 grid = [[0, 0, 0], [1, 1, 0], [0, 0, 0]] start = Node(0, 0, 0, 0) target = Node(2, 2, 0, 0) result = astar_search(start, target, grid) print(result) ``` 以上代码实现了A寻路算法,并可用于寻找给定地图中起点到目标点的最短路径。其中,`grid`是二维列表表示地图,在地图中,0表示可通过的节点,1表示不可通过的节点。`start`表示起点,`target`表示目标点。通过调用`astar_search`函数,将起点、目标点和地图作为参数进传递,即可得到最短路径的长度。 ### 回答3: A寻路算法是一种常用于寻找最短路径的算法,广泛应用于游戏开发、路径规划等领域。下面是使用Python实现A寻路算法代码: ```python # 定义地图和起终点 map = [ [0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0] ] start = (1, 1) # 起点坐标 goal = (6, 5) # 终点坐标 # 定义辅助函数 def heuristic(pos1, pos2): # 估算两点之间的距离(启发函数) x1, y1 = pos1 x2, y2 = pos2 return abs(x1 - x2) + abs(y1 - y2) def get_neighbors(pos): # 获取当前位置的邻近位置 x, y = pos neighbors = [] for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if dx == dy == 0: # 排除当前位置 continue new_x, new_y = x + dx, y + dy if 0 <= new_x < len(map) and 0 <= new_y < len(map[0]) and map[new_x][new_y] == 0: neighbors.append((new_x, new_y)) return neighbors # 定义A算法函数 def astar_search(start, goal): # 初始化起点和终点 open_list = [start] # 待探索的节点 came_from = {} # 记录路径中每个节点的上一个节点 g_score = {start: 0} # 起点到每个节点的实际代价 f_score = {start: heuristic(start, goal)} # 起点到每个节点的估算代价(f_score = g_score + h_score) while open_list: current = min(open_list, key=lambda x: f_score[x]) # 获取f_score最小的节点 if current == goal: # 已到达终点 path = [] while current in came_from: path.append(current) current = came_from[current] path.append(start) path.reverse() return path open_list.remove(current) for neighbor in get_neighbors(current): g_temp = g_score[current] + 1 # 节点到邻近节点的代价为1 if neighbor not in g_score or g_temp < g_score[neighbor]: came_from[neighbor] = current g_score[neighbor] = g_temp f_score[neighbor] = g_temp + heuristic(neighbor, goal) if neighbor not in open_list: open_list.append(neighbor) return [] # 未找到路径 # 在地图上运A算法 path = astar_search(start, goal) print("路径: ", path) ``` 该代码首先定义了一个地图,使用0表示可走的区域,使用1表示障碍物。将起点和终点设定好后,通过`heuristic`函数计算两点间的估算距离。`get_neighbors`函数用于获取当前位置的邻近位置。 `astar_search`函数是实现A算法的核心部分。其中,`open_list`用于存放待探索的节点,`came_from`用于记录路径中每个节点的上一个节点,`g_score`用于记录起点到每个节点的实际代价,`f_score`用于记录起点到每个节点的估算代价。算法使用一个循环不断探索下一个最有可能的节点,直到找到终点或无法找到路径为止。 最后,在地图上运A算法,并输出结果路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值