什么是A*(Astar)算法?(简单叙述)

目录

简介

A*算法的原理与思想

A*算法处理与搜索

实例(引用见文末)


 

简介

A*算法(启发式搜索)的首要条件是在静态路网中,相对于广度优先遍历(FBS)求最短路径的最有效算法(FBS缺点是效率低耗时久,而A*更高效)。

A*算法的原理与思想

运用了一个很重要的式子:f(n)=g(n)+h(n)

什么是A*(Astar)算法?(简单叙述)_第1张图片

A*算法结合了贪心算法(深度优先)与Dijkatra算法(广度优先),优先计算代价更低的方向。

A*算法处理与搜索

  1. 将整个地图网格化,可以理解为化为一个个像素点,即栅格法,将每一个像素点作为一个节点。
  2. 给每一个节点定义一个属性:①可通过②不可通过。
  3. 定义一个列表集合openlist和closelist,给每一个节点都可有一个状态openlist或closelist,分别属于两个集合。(属性为不可通过的节点默认为closelist状态,该节点就属于closelist集合)
  4. openlist为待考察节点,closelist为已考察节点。先以初位置节点为父节点,其状态为closelist,以其为中心的九宫格的其余八个节点为子节点,都附加状态openlist。
  5. 定义横纵移动的代价为10,斜向移动大家为14.
  6. 什么是A*(Astar)算法?(简单叙述)_第2张图片
  7. 选择f(n)值最小的节点将他从openlist移入closelist
  8. 首先考察g(n)其他 4 个相邻的方格均在 open list 中,我们需要检查经由这个方格到达那里的路径是否更好,使用g(n) 值来判定。让我们看看上面的方格。它现在的 G 值为 14 。如果我们经由当前方格到达那里, g(n)值将会为 20(其中 10 为到达当前方格的 g(n) 值,此外还要加上从当前方格纵向移动到上面方格的 g(n) 值 10) 。显然 20 比 14 大,因此这不是最优的路径。如果你看图你就会明白。直接从起点沿对角线移动到那个方格比先横向移动再纵向移动要好。
  9. 再考察h(n),按照曼哈顿距离计算估计代价,再计算出f(n)=g(n)+h(n)的值。
  10. 以此类推,分别计算出剩余openlist的节点的f(n)值,挑选最小的代价节点一刀closelist中。
  11. 从openlist中选择f(n)最小的节点放入closelist中并将它视作新的父节点,按照以上步骤类推,不断的重复,一直到搜索到终点节点,完成路径搜索,结束算法。

实例(引用见文末)

什么是A*(Astar)算法?(简单叙述)_第3张图片

如图浅绿色点到草绿色点。

clear;
clc;
clf;
figure(1);
map =[
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0
0	0	0	.3	0	0	0	1	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	1	0	0	.7	0	0	0	0	0
0	0	0	0	0	0	1	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	1	1	1	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	1	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
];
pcolor(map)
colormap summer
[row,col] = size(map);
[start_px,start_py] = find(map == .3);
[end_px,end_py] = find(map == .7);

close = struct([]); 
closelen = 0;
open = struct([]); 
openlen = 0;

%% 将起点添加到open列表
open(1).row = start_px;
open(1).col = start_py;
open(1).g = 0;
open(1).h = abs(end_py - start_py) + abs(end_px - start_px);
openlen = openlen + 1;
%% 四种运动格式
sport = [0,1;0,-1;-1,0;1,0];
backNum = 0;
prev = [];
while openlen > 0
    %% 获取代价最小的值
    for i = 1:openlen
        f(i,:) = [i,open(i).g + open(i).h];       
    end
    f1 = sortrows(f,2);
    current = open(f1(1));
    choose = 0;
    chooseArr = [];
    %% 回溯将走过的点标记出来
     if current.row == end_px && current.col == end_py
         i = 1;
         while(i<=size(prev,1))
             if prev(i,3) == current.row && prev(i,4) == current.col
                 choose = choose +1;
                 chooseArr(choose,1) = prev(i,1);
                 chooseArr(choose,2) = prev(i,2);
                 current.row =  prev(i,1);
                 current.col =  prev(i,2);
                 i = 1;
             else
                 i = i + 1;
             end
         end      
         for j = 1: size(chooseArr,1)
                map(chooseArr(j,1),chooseArr(j,2)) = 0.5;
         end
         figure(2);
         pcolor(map);
         colormap winter;
         return;         
     end
     closelen = closelen + 1;
     close(closelen).row = open(f1(1)).row;
     close(closelen).col = open(f1(1)).col;
     close(closelen).g = open(f1(1)).g;
     close(closelen).h = open(f1(1)).h;   
     open(f1(1)) = [];
     openlen = openlen -1;     
    for i = 1:4
        dimNormal = all([current.row,current.col]+sport(i,:)>0) ...
            && current.row+sport(i,1)<=row && current.col+sport(i,2)<=col;
        neighbor.row = current.row + sport(i,1);
        neighbor.col = current.col + sport(i,2);
        neighbor.g = abs(start_px - neighbor.row) + abs(start_py - neighbor.col);
        neighbor.h = abs(end_px - neighbor.row) + abs(end_py - neighbor.col);
    
    
        if dimNormal
            inCloseFlag = 0; 
            if closelen ==0
            else
                for j = 1:closelen
                    if close(j).row == neighbor.row && close(j).col ==neighbor.col
                        inCloseFlag = 1;
                        break;
                    end
                end
            end
        
            if inCloseFlag
                continue;
            end
            
            temp_g = current.g + abs(current.row - neighbor.row) + abs(current.col - neighbor.col);
            inOpenFlag = 0;
            for j =1:openlen
                if open(j).row == neighbor.row && open(j).col ==neighbor.col
                    inOpenFlag = 1;
                    break;
                end
            end        
            if ~inOpenFlag && map(neighbor.row,neighbor.col) ~= 1
                openlen = openlen + 1;
                open(openlen).row = neighbor.row;
                open(openlen).col = neighbor.col;
                open(openlen).g = abs(start_px - neighbor.row) + abs(start_py - neighbor.col);
                open(openlen).h = abs(end_px - neighbor.row) + abs(end_py - neighbor.col);               
            elseif temp_g >= neighbor.g
                continue;
            end
                backNum = backNum +1;
                prev(backNum,:) = [current.row ,current.col,neighbor.row ,neighbor.col];
                neighbor.g = temp_g;            
        else
            continue;
        end
    end     
end

   结果为

什么是A*(Astar)算法?(简单叙述)_第4张图片

参考与引用http://www.gamedev.net/reference/articles/article2003.asp

                 https://b23.tv/I3GLzp

                 https://blog.csdn.net/lmq_zzz/article/details/88999480

你可能感兴趣的:(算法)