A*演算法與matlab實現
A*演算法是一種尋路演算法,常常被用在遊戲智慧ai的自動尋路過程等等,它較之於圖論的最短路演算法而言,更加適用於節點巨大的情況下,但是該演算法是一種啟發式搜尋演算法,並不能保證總是找到最優路徑。
A*的演算法思想如下:
定義兩個函式:f和g,其中f揭示當前點到出發點的距離,g揭示當前點到終點的距離。
對於每個將要遍歷的點,h=f+g是其啟發函式,每次選擇待選擇節點中啟發函式值最大的節點放入路徑之中,重複此步驟。
演算法具體步驟如下:
- 將方塊新增到open列表中,該列表有最小的和值。且將這個方塊稱為S吧。
- 將S從open列表移除,然後新增S到closed列表中。
- 對於與S相鄰的每一塊可通行的方塊T:
-
- 如果T在closed列表中:不管它。
- 如果T不在open列表中:新增它然後計算出它的和值。
- 如果T已經在open列表中:當我們使用當前生成的路徑到達那裡時,檢查F G和值是否更小。如果是,更新它的和值和它的前繼。
因為matlab的畫圖功能比較強大,所以下面使用matlab實現最基本的A*演算法:
function[open,close]=Astar(map)
[row,col]=size(map);
close=struct('row',-1,'col',-1,'g',0,'h',0);%????????????????????????
closelen=1;
open=struct('row'
openlen=0;
bindex=1;
fork=1:row
forj=1:col
ifmap(k,j)==1
barrierrow(bindex)=-k;
barriercol(bindex)=j;
bindex=bindex+1;
end
end
end
%????????????
fori=1:row
forj=1:col
if
endrow=i;
endcol=j;
break;
end
end
end
%????????????????????close
fori=1:row
forj=1:col
ifmap(i,j)==5
startrow=i;
startcol=j;
close(1).row=i;
close(1).col=j;
break;
end
end
end
%??????????????????open
%????????
direct=[0 -1;0 1;-1 0;1 0];
fori=1:4
ifall([close(1).row,close(1).col]+direct(i,:)>0) && close(1).row+direct(i,1)<=row && close(1).col+direct(i,2)<=col && map(close(1).row+direct(i,1),close(1).col+direct(i,2))~=1
open(openlen+1).row=close(1).row+direct(i,1);
open(openlen+1).col=close(1).col+direct(i,2);
openlen=openlen+1;
%????g??????h????????
open(openlen).g=1;
open(openlen).h=abs(endrow-open(openlen).row)+abs(endcol-open(openlen).col);
end
end
% close
% open.h
%????????open??colse????????????????????????????????????
whileopenlen>0
%????????????g+h????open????????
min = realmax;
fori=1:openlen
ifopen(i).g+open(i).h<=min
min=open(i).g+open(i).h;
sindex=i;
end
end
%??s????????close????????open??
close(closelen+1).row=open(sindex).row;
close(closelen+1).col=open(sindex).col;
close(closelen+1).g=open(sindex).g;
close(closelen+1).h=open(sindex).h;
closelen=closelen+1;
% openlen=openlen-1;
% for i=sindex:openlen
% open(i)=open(i+1);
% end
% open(openlen+1)=[];
openlen=0;
%??????????
pause(0.3)
img = zeros(row,col);
img(startrow,startcol)=10;
fork=1:row
forj=1:col
ifmap(k,j)==1
img(k,j)=5;
end
end
end
fork=2:closelen
img(close(k).row,close(k).col)=3;
end
img(endrow,endcol)=10;
imagesc(img*10);
%??????????????????????
ifclose(closelen).row == endrow && close(closelen).col==endcol
break;
end
%??????????????????????????????????????????open??
fori=1:4
ifall([close(closelen).row,close(closelen).col]+direct(i,:)>0) && close(closelen).row+direct(i,1)<=row && close(closelen).col+direct(i,2)<=col && map(close(closelen).row+direct(i,1),close(closelen).col+direct(i,2))~=1
%????????????close??
flag=false;
form=1:closelen
ifclose(m).row==close(closelen).row+direct(i,1) && close(m).col==close(closelen).col+direct(i,2)
flag=true;
break;
end
end
ifflag
continue;
end
%????????????open??
flag=false;
form=1:openlen
ifopen(m).row==close(closelen).row+direct(i,1) && open(m).col==close(closelen).col+direct(i,2)
flag=true;
break;
end
end
ifflag
%more????????
continue;
else %open??????????
open(openlen+1).row=close(closelen).row+direct(i,1);
open(openlen+1).col=close(closelen).col+direct(i,2);
openlen=openlen+1;
%????g??????h????????
open(openlen).g=close(closelen).g+1;
open(openlen).h=abs(endrow-open(openlen).row)+abs(endcol-open(openlen).col);
h=open(openlen).h
end
end
end
end
執行截圖如下: