A*算法MATLAB代码

A_star.c

clc
clear
close all
%% 画地图

% 栅格地图的行数、列数定义
m = 7;
n = 7;
start_node = [2, 3];%起点
target_node = [6, 3];%终点
obs = [4,2; 4,3; 4,4];%障碍物
%画栅格横线
for i = 1:m
    plot([0,n], [i, i], 'k');
    hold on
end
%画栅格竖线   
for j = 1:n
     plot([j, j], [0, m], 'k');
end

axis equal%等比坐标轴,使得每个坐标轴都具有均匀的刻度间隔
xlim([0, n]);
ylim([0, m]); %xy轴上下限  

% 绘制障碍物、起止点颜色块
fill([start_node(1)-1, start_node(1), start_node(1), start_node(1)-1],...
    [start_node(2)-1, start_node(2)-1 , start_node(2), start_node(2)], 'g');

fill([target_node(1)-1, target_node(1), target_node(1), target_node(1)-1],...
    [target_node(2)-1, target_node(2)-1 , target_node(2), target_node(2)], 'r');

for i = 1:size(obs,1)%返回矩阵行数
    temp = obs(i,:);
    fill([temp(1)-1, temp(1), temp(1), temp(1)-1],...
        [temp(2)-1, temp(2)-1 , temp(2), temp(2)], 'b');
end

%% 预处理

% 初始化closeList,    不能与重复
closeList = start_node;
closeList_path = {start_node,start_node};
closeList_cost = 0;
child_nodes = child_nodes_cal(start_node,  m, n, obs, closeList); %子节点搜索函数 

% 初始化openList
openList = child_nodes;
for i = 1:size(openList,1)
    openList_path{i,1} = openList(i,:);
    openList_path{i,2} = [start_node;openList(i,:)];%从初始点到第i个子节点
end

for i = 1:size(openList, 1)
    g = norm(start_node - openList(i,1:2));%norm求范数,返回最大奇异值;abs求绝对值
    h = abs(target_node(1) - openList(i,1)) + abs(target_node(2) - openList(i,2));
    %终点横坐标距离加纵坐标距离
    f = g + h;
    openList_cost(i,:) = [g, h, f];
end

%% 开始搜索
% 从openList开始搜索移动代价最小的节点
[~, min_idx] = min(openList_cost(:,3));%输出openlist_cost表中最小值的位置
parent_node = openList(min_idx,:);%父节点为代价最小节点


%% 进入循环
flag = 1;
while flag   
    
    % 找出父节点的忽略closeList的子节点
    child_nodes = child_nodes_cal(parent_node,  m, n, obs, closeList); 
    
    % 判断这些子节点是否在openList中,若在,则比较更新;没在则追加到openList中
    for i = 1:size(child_nodes,1)
        child_node = child_nodes(i,:);
        [in_flag,openList_idx] = ismember(child_node, openList, 'rows');%ismember函数表示子节点在open表中则返回1,判断flag,输出此子节点在openlist表中的位置
        g = openList_cost(min_idx, 1) + norm(parent_node - child_node);%按照新父节点计算此子节点的g,h值
        h = abs(child_node(1) - target_node(1)) + abs(child_node(2) - target_node(2));
        f = g+h;
        
        if in_flag   % 若在,比较更新g和f        
            if g < openList_cost(openList_idx,1)
                openList_cost(openList_idx, 1) = g;%将openlist_cost表中第id个位置的第一个数更新为以新父节点计算的g值
                openList_cost(openList_idx, 3) = f;
                openList_path{openList_idx,2} = [openList_path{min_idx,2}; child_node];
            end
        else         % 若不在,追加到openList
            openList(end+1,:) = child_node;
            openList_cost(end+1, :) = [g, h, f];
            openList_path{end+1, 1} = child_node;
            openList_path{end, 2} = [openList_path{min_idx,2}; child_node];
        end
    end
   
    
    % 从openList移除移动代价最小的节点到 closeList
    closeList(end+1,: ) =  openList(min_idx,:);
    closeList_cost(end+1,1) =   openList_cost(min_idx,3);
    closeList_path(end+1,:) = openList_path(min_idx,:);
    openList(min_idx,:) = [];%openlist表中已跳出的最小值位置设为空
    openList_cost(min_idx,:) = [];
    openList_path(min_idx,:) = [];
 
    % 重新搜索:从openList搜索移动代价最小的节点(重复步骤)
    [~, min_idx] = min(openList_cost(:,3));
    parent_node = openList(min_idx,:);
    
    % 判断是否搜索到终点
    if parent_node == target_node
        closeList(end+1,: ) =  openList(min_idx,:);
        closeList_cost(end+1,1) =   openList_cost(min_idx,1);
        closeList_path(end+1,:) = openList_path(min_idx,:);
        flag = 0;
    end
end
    
    
%% 画路径
path_opt = closeList_path{end,2};
path_opt(:,1) = path_opt(:,1)-0.5;
path_opt(:,2) = path_opt(:,2)-0.5;
scatter(path_opt(:,1), path_opt(:,2), 'k');%绘制散点图
plot(path_opt(:,1), path_opt(:,2), 'k');

 子函数,即找到父节点相邻且满足条件的子节点的函数

child_nodes_cal.m

f(x) = exp(-x)+x^2;child_nodes = child_nodes_cal(parent_node, m, n, obs, closeList)

child_nodes = [];
field = [1,1; n,1; n,m; 1,m];

% 第1个子节点
child_node = [parent_node(1)-1, parent_node(2)+1];
if inpolygon(child_node(1), child_node(2), field(:,1), field(:,2))%判断点是否在多边形内
    if ~ismember(child_node, obs, 'rows')
        child_nodes = [child_nodes; child_node];
    end
end

% 第2个子节点
child_node = [parent_node(1), parent_node(2)+1];
if inpolygon(child_node(1), child_node(2), field(:,1), field(:,2))
    if ~ismember(child_node, obs, 'rows')
        child_nodes = [child_nodes; child_node];
    end
end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A*算法是一种常用的启发式搜索算法,用于在图形或网络中找到最短路径。下面是一个简单的A*算法Matlab代码示例: ```matlab function [path, cost] = Astar(start, goal, graph, heuristic) % 初始化起始节点和目标节点 startNode = Node(start, 0, heuristic(start)); goalNode = Node(goal, Inf, 0); % 初始化开放列表和关闭列表 openList = PriorityQueue(); openList.insert(startNode); closedList = containers.Map(); while ~openList.isEmpty() % 从开放列表中选择具有最小总代价的节点 currentNode = openList.pop(); % 如果当前节点是目标节点,则找到了最短路径 if currentNode == goalNode path = reconstructPath(currentNode); cost = currentNode.g; return; end % 将当前节点添加到关闭列表中 closedList(currentNode.id) = currentNode; % 获取当前节点的邻居节点 neighbors = getNeighbors(currentNode, graph); for i = 1:length(neighbors) neighbor = neighbors(i); % 如果邻居节点已经在关闭列表中,则跳过 if isKey(closedList, neighbor.id) continue; end % 计算邻居节点的代价 gScore = currentNode.g + distance(currentNode, neighbor); % 如果邻居节点不在开放列表中,则将其添加到开放列表中 if ~openList.contains(neighbor) neighbor.g = gScore; neighbor.h = heuristic(neighbor.id); neighbor.parent = currentNode; openList.insert(neighbor); else % 如果邻居节点已经在开放列表中,并且新的代价更小,则更新代价和父节点 if gScore < neighbor.g neighbor.g = gScore; neighbor.parent = currentNode; openList.updatePriority(neighbor); end end end end % 如果开放列表为空,则无法找到最短路径 path = []; cost = Inf; end function path = reconstructPath(node) % 从目标节点开始,沿着父节点回溯,构建最短路径 path = []; while ~isempty(node) path = [node.id, path]; node = node.parent; end end function distance = distance(node1, node2) % 计算两个节点之间的距离(可以根据具体情况进行修改) distance = norm(node1.id - node2.id); end function neighbors = getNeighbors(node, graph) % 获取当前节点的邻居节点(可以根据具体情况进行修改) neighbors = graph(node.id); end classdef Node properties id % 节点ID g % 从起始节点到当前节点的代价 h % 从当前节点到目标节点的启发式估计代价 parent % 父节点 end methods function obj = Node(id, g, h) obj.id = id; obj.g = g; obj.h = h; obj.parent = []; end end end classdef PriorityQueue properties elements % 元素列表 priorities % 优先级列表 end methods function obj = PriorityQueue() obj.elements = {}; obj.priorities = []; end function insert(obj, element) % 将元素插入到优先级队列中 obj.elements{end+1} = element; obj.priorities(end+1) = element.g + element.h; end function element = pop(obj) % 弹出具有最小优先级的元素 [~, index] = min(obj.priorities); element = obj.elements{index}; obj.elements(index) = []; obj.priorities(index) = []; end function updatePriority(obj, element) % 更新元素的优先级 index = find(obj.elements == element); obj.priorities(index) = element.g + element.h; end function containsElement = contains(obj, element) % 判断元素是否在优先级队列中 containsElement = any(obj.elements == element); end function isEmptyQueue = isEmpty(obj) % 判断优先级队列是否为空 isEmptyQueue = isempty(obj.elements); end end end ``` 这段代码实现了A*算法的基本逻辑,包括节点类、优先级队列类和主函数。你可以根据自己的需求进行修改和扩展。希望对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值