1. 程式人生 > >A*演算法與matlab實現

A*演算法與matlab實現

A*演算法是一種尋路演算法,常常被用在遊戲智慧ai的自動尋路過程等等,它較之於圖論的最短路演算法而言,更加適用於節點巨大的情況下,但是該演算法是一種啟發式搜尋演算法,並不能保證總是找到最優路徑。

A*的演算法思想如下:

定義兩個函式:f和g,其中f揭示當前點到出發點的距離,g揭示當前點到終點的距離。

對於每個將要遍歷的點,h=f+g是其啟發函式,每次選擇待選擇節點中啟發函式值最大的節點放入路徑之中,重複此步驟。

演算法具體步驟如下:

  1. 將方塊新增到open列表中,該列表有最小的和值。且將這個方塊稱為S吧。
  2. 將S從open列表移除,然後新增S到closed列表中。
  3. 對於與S相鄰的每一塊可通行的方塊T:
    1. 如果T在closed列表中:不管它。
    2. 如果T不在open列表中:新增它然後計算出它的和值。
    3. 如果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'

,-1,'col',-1,'g',-1,'h',-1);%????????????????????????

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

map(i,j)==2

            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

執行截圖如下: