1. 程式人生 > >一個高效的a *尋路演算法(八方向)

一個高效的a *尋路演算法(八方向)

http://blog.csdn.net/onafioo/article/details/41089579

這種寫法比較垃圾,表現在每次搜尋一個點要遍歷整個地圖那麼大的陣列,如果地圖為256 * 256,每次搜尋都要執行65535次,如果遍歷多個點就是n * 65535,速度上實在是太垃圾了

簡單說下思路,以後補充演算法

優化重點在表在開放和關閉表的遍歷上,這兩個地方優化後,斯達會大量提速

親密只用來查詢所以可以用雜湊這樣就避免了遍歷

開啟首先用來查詢是否有相同的點如果有會比較替換F值,其次用來遍歷查詢最小點,如果用優先順序佇列加雜湊可以減少2次遍歷,但是相同點替換F值和父節點就沒辦法了,只能遍歷一次(但一般找到該找的點就可以休息,不需要完整遍歷)

如果用Javac#,由於有垃圾回收機制,為了避免產生過多垃圾降低垃圾回收壓力,可以用空閒物件池來避免頻繁建立節點,控制記憶體洩露

之所以說這個a *演算法高效,是因為它的開放列表和close-list使用的完全是靜態陣列,這樣就極大地降低了入棧出棧的負擔。這個程式碼非常值得推薦。 用法很簡單: 結果route_pt[]=零; / / result_pt是一個簡單類,它只有兩個成員變數:int x和int y。 / /引數說明:地圖是一個二維陣列,具體見程式註釋 AStarRoute2 asr = new AStarRoute2(地圖,start_x,start_y、end_x end_y);
嘗試{    結果= asr.getResult(); }捕捉(例外的前女友){ } 如果結果! =零那麼尋路就成功了。 注意:最後獲得的路徑,是從終點指向起點的。您可以把兩組引數倒過來傳,以獲得正常方向的返回值。 本人對賈羅德的程式碼略作修改,主要是用迴圈取代了遞迴,避免棧溢位。 這是本人修改後的八方向尋路演算法。如下: 進口java.util.ArrayList; 公開課AStarRoute2 {     私人int[][]地圖;/ /地圖矩陣,0表示能通過,1表示不能通過     私人int map_w;  / /地圖寬度     私人int map_h;  / /地圖高度     私人int start_x;
/ /起點座標X
    私人int start_y;/ /起點座標Y     私人int goal_x;/ /終點座標X     私人int goal_y;/ /終點座標Y     私人布林closeList[][];          / /關閉列表     公共int openList[][][];            / /開啟列表     私人int openListLength;     私有靜態最終int存在= 1;     私有靜態最終int NOT_EXIST = 0;     私有靜態最終int ISEXIST = 0;     私有靜態最終int費用= 1;  / /自身的代價     私有靜態最終int距離= 2;  / /距離的代價     私有靜態最終int成本= 3;      / /消耗的總代價     私有靜態最終int FATHER_DIR = 4;/ /父節點的方向     公共靜態最終int DIR_NULL = 0;     公共靜態最終int DIR_DOWN = 1;  / /方向:下     公共靜態最終int DIR_UP = 2;    / /方向:上     公共靜態最終int DIR_LEFT = 3;  / /方向:左     公共靜態最終int DIR_RIGHT = 4;  / /方向右     公共靜態最終int DIR_UP_LEFT = 5;     公共靜態最終int DIR_UP_RIGHT = 6;     公共靜態最終int DIR_DOWN_LEFT = 7;     公共靜態最終int DIR_DOWN_RIGHT = 8;     私人int astar_counter;              / /演算法巢狀深度     私人布林isFound;                / /是否找到路徑     公共AStarRoute2(int[][]mx,int sx,int sy,int gx,int gy){         start_x = sx;         start_y = sy;         goal_x= gx;         goal_y= gy;         地圖  = mx;        map_w= mx.length;         map_h= mx[0]. length;         astar_counter = 5000;         initCloseList();         initOpenList(goal_x goal_y);     }     / /得到地圖上這一點的消耗值     私人int getMapExpense(int x,int y,int dir)     {         如果(dir < 5){             返回10;         其他} {             返回14;         }     }     / /得到距離的消耗值     私人int getDistance(int x,int y,int,int)等等)     {         返回10 *(數學。 abs(x - ex)+數學。 abs(y -迪士尼));     }     / /得到給定座標格子此時的總消耗值     私人int getCost(int x,int y)     {         返回openList[x][y][費用];     }     / /開始尋路     公共空間searchPath()     {         addOpenList(start_x start_y);         斯達(start_x start_y);     }     / /尋路     私人空間斯達(int x,int y)     {         / /控制演算法深度         (int t = 0;t < astar_counter;t + +){             如果(((x = = goal_x)& &(y = = goal_y))){                 isFound = true;                 返回;             }             else if((openListLength = = 0)){                 isFound = false;                 返回;             }             removeOpenList(x,y);             addCloseList(x,y);             / /該點周圍能夠行走的點             addNewOpenList(x,y,x,y + 1,DIR_UP);             addNewOpenList(x,y,x,y - 1,DIR_DOWN);             addNewOpenList(x,y,x - 1,y,DIR_RIGHT);             addNewOpenList(x,y,x + 1,y,DIR_LEFT);             addNewOpenList(x,y,x + 1,y + 1,DIR_UP_LEFT);             addNewOpenList(x,y,x - 1,y + 1,DIR_UP_RIGHT);             addNewOpenList(x,y,x + 1,y - 1,DIR_DOWN_LEFT);             addNewOpenList(x,y,x - 1,y - 1,DIR_DOWN_RIGHT);             / /找到估值最小的點,進行下一輪演算法             int成本= 0 x7fffffff;             for(int i = 0;我< map_w;+ +){                 for(int j = 0;< map_h;j + +){                     如果(openList[我][j][ISEXIST]= =存在){                         如果(成本> getCost(i,j)){                             成本= getCost(i,j);                             x =我;                             y = j;                         }                     }                 }             }         }         / /演算法超深         isFound = false;         返回;     }     / /新增一個新的節點     私人空間addNewOpenList(int x,int y,int newX,int newY,int dir)     {         如果(isCanPass(newX newY)){             如果(openList[newX][newY][ISEXIST]= =存在){                 如果(openList[x][y][費用]+ getMapExpense(newX、newY dir)<                     openList[newX][newY][費用]){                     setFatherDir(newX newY dir);                     setCost(newX newY,x,y,dir);                 }             其他} {                 addOpenList(newX newY);                 setFatherDir(newX newY dir);                 setCost(newX newY,x,y,dir);             }         }     }     / /設定消耗值     私人空間setCost(int x,int y,int,int,int dir)     {         openList[x][y][費用]= openList[例][是][費用] + getMapExpense(x,y,dir);         openList[x][y][距離]= getDistance(x,y,交貨哦,是吧);         openList[x][y][費用]= openList[x][y][費用] + openList[x][y](距離);     }     / /設定父節點方向     私人空間setFatherDir(int x,int y,int dir)     {         openList[x][y][FATHER_DIR]= dir;     }     / /判斷一個點是否可以通過     私人布林isCanPass(int x,int y)     {         / /超出邊界         如果(x < 0 | | x > = map_w | | y < 0 | | y > = map_h){             返回錯誤;         }         / /地圖不通         如果(map[x][y]! = 0){             返回錯誤;         }         / /在關閉列表中         如果(isInCloseList(x,y)){             返回錯誤;         }         返回true;     }     / /移除開啟列表的一個元素     私人空間removeOpenList(int x,int y)     {         如果(openList[x][y][ISEXIST]= =存在){             openList[x][y][ISEXIST]= NOT_EXIST;             openListLength——;         }     }     / /判斷一點是否在關閉列表中     私人布林isInCloseList(int x,int y)     {         返回closeList[x][y];     }     / /新增關閉列表     私人空間addCloseList(int x,int y)     {         closeList[x][y]= true;     }     / /新增開啟列表     私人空間addOpenList(int x,int y)     {         如果(openList[x][y][ISEXIST]= = NOT_EXIST){             openList[x][y][ISEXIST]=存在;             openListLength + +;         }     }     / /初始化關閉列表     私人空間initCloseList()     {         closeList = new布林[map_w][map_h];         for(int i = 0;我< map_w;+ +){             for(int j = 0;< map_h;j + +){                 closeList[我][j]= false;             }         }     }     / /初始化開啟列表     私人空間initOpenList(int,int)等等)     {         openList= new int[map_w][map_h][5];         for(int i = 0;我< map_w;+ +){             for(int j = 0;< map_h;j + +){                 openList[我][j][ISEXIST]= NOT_EXIST;                 openList[我][j][費用]= getMapExpense(i,j,DIR_NULL);                 openList[我][j][距離]= getDistance(i,j,交貨哦,是吧);                 openList[我][j][費用]= openList[我][j][費用] + openList[我][j](距離);                 openList[我][j][FATHER_DIR]= DIR_NULL;             }         }         openListLength = 0;     }     / /獲得尋路結果     公共route_pt[]getResult(){         route_pt[]的結果;         ArrayList < route_pt >路線;         searchPath();         如果(! isFound){             返回null;         }         路線= new ArrayList < route_pt >();         / / openList是從目標點向起始點倒推的。         int第九= goal_x;         int iY = goal_y;         而(第九! = start_x | | iY ! = start_y)){             路線。 新增(新route_pt(第九,iY));             開關(openList[iX][iY][FATHER_DIR]){             案例DIR_DOWN:        iY + +;          打破;             案例DIR_UP:          iY——;          打破;             案例DIR_LEFT:        第九,;          打破;             案例DIR_RIGHT:      第九+ +;          打破;             案例DIR_UP_LEFT:    第九,;iY——;  打破;             案例DIR_UP_RIGHT:    第九+ +;iY——;  打破;             案例DIR_DOWN_LEFT:  第九,;iY + +;  打破;             案例DIR_DOWN_RIGHT:  第九+ +;iY + +;  打破;             }         }         int大小= route.size();         結果= new route_pt(大小);         for(int i = 0;我+ +){ <大小;             結果新route_pt[我]=((route_pt)route.get(我));         }         返回結果;     } }

相關推薦

一個高效a *演算法(方向)

http://blog.csdn.net/onafioo/article/details/41089579 這種寫法比較垃圾,表現在每次搜尋一個點要遍歷整個地圖那麼大的陣列,如果地圖為256 * 256,每次搜尋都要執行65535次,如果遍歷多個點就是n * 65

unity中的一個簡單易用的A*演算法

以前專案中用到了尋路,就寫了個A*尋路的演算法類,感覺還不錯,這裡分享出來。A*演算法的原理網上有很多,這裡只簡單說一下我這個演算法的邏輯:*我的這個演算法裡面沒有關閉列表,因為我會根據地圖資料建立一個對應的節點資料的陣列,每個節點資料記錄自己當前的狀態,是開啟還是關閉的。節

理解A*演算法過程

   這兩天研究了下 A* 尋路演算法, 主要學習了這篇文章, 但這篇翻譯得不是很好, 我花了很久才看明白文章中的各種指代. 特寫此篇部落格用來總結, 並寫了尋路演算法的程式碼, 覺得有用的同學可以看看. 另外因為圖片製作起來比較麻煩, 所以我用的是原文裡的圖片. &n

淺談遊戲中的A*演算法

本文為銳亞教育原創文章,轉載請註明轉載自銳亞教育 A*尋路 A*演算法基本原理 A*(唸作A星)演算法對初學者來說的確有些難度。本文並不試圖對這個話題作權威性的陳述,取而代之的是描述演算法的原理,使你可以在進一步的閱讀中理解其他相關的資

A*演算法補充知識

A*演算法 輔助知識 unity視覺化輔助工具Gizmos Gizmos.color =Color.red;//設定畫筆的顏色 Gizmos.DrawWireCube(位置,Vector3(長寬高));//畫出一個範圍框: Gizmos.DrawCube(位置,三維屬性長寬高); /

A*演算法之解決目標點不可達問題

在遊戲世界的尋路中,通常會有這樣一種情況:在小地圖上點選目標點時,點選到了障礙物或者建築上,然後遊戲會提示我們目標地點無法到達。玩家必須非常小心的在小地圖上點選目標區域的空白部分,才能移動到目標地點。那麼,有沒有辦法來改進一下這種不友好的體驗呢? 下面給出兩種方法: 最近

A*演算法的優化與改進

提要通過對上一篇A*尋路演算法的學習,我們對A*尋路應該有一定的瞭解了,但實際應用中,需要對演算法進行一些改進和優化。 Iterative Deepening Depth-first search- 迭代深化深度優先搜尋在深度優先搜尋中一個比較坑爹情形就是在搜尋樹的一枝上沒有

第四章 Dijkstra和A*演算法

尋路 尋路希望ai中的角色能夠計算一條從當前位置到目標位置合適的路徑,並且這條路徑能夠儘可能的合理和短。 在我們的ai模型中,尋路在決策和移動之間。遊戲中大多數尋路的實現是基於a星演算法,但是它不能直接使用關卡資料工作,需要轉換成特別的資料結構:有向非負權重

RPG遊戲製作-03-人物行走及A*演算法

在遊戲中,可以控制人物的方法一般有:1.鍵盤 2.虛擬搖桿 3.滑鼠 4.手機觸碰。鍵盤一般是在PC端較為常用,如果在遊戲中使用wasd等操作人物的話,那麼在移植到安卓端時,就需要使用虛擬搖桿或虛擬按鈕來模擬鍵盤,以實現處理的統一性。滑鼠類似於手機的單點觸碰,而手機觸碰一般分

A* 演算法

寫在前面 再來填一個坑。之前一直說要寫的A* 終於有空補上了,本篇部落格首先會介紹最基礎的A* 實現,在簡單A* 的基礎上,嘗試實現稍複雜的A* 演算法(帶有高度資訊的地形,允許對角線尋路等)。 A*演算法簡介 本部落格不準備探討A* 演算法的原理,這

A*演算法基於C#實現

 玩過即時戰略,RPG等型別的遊戲的朋友一定會知道,當我們用滑鼠選取某些單位並命令其到達地圖上確定的位置時,這些單位總是可以自動的選擇最短的路徑到達。這個時候我們就會聯想到大名鼎鼎的A*尋路演算法,下文簡略介紹演算法實現原理,並附上C#實現方法。using System; u

A*演算法的C++簡單實現

2007/8/13 17:26:59 #include <iostream> #include <ctime> #include <list> #include <algorithm> #include <cassert&

Unity A*演算法(人物移動AI)

最近閒來無事,從網上看了一些大神的心得,再融合自己的體會,寫了一個簡單點的尋路演算法,廢話不多說,直接上程式碼 <Grid> usingUnityEngine; usingSystem.Collections; usingS

A*演算法與它的速度

如果你是一個遊戲開發者,或者開發過一些關於人工智慧的遊戲,你一定知道A*演算法,如果沒有接觸過此類的東東,那麼看了這一篇文章,你會對A*演算法從不知道變得了解,從瞭解變得理解。我不是一個純粹的遊戲開發者,我只是因為喜歡而研究,因為興趣而開發,從一些很小的遊戲開始,直到接觸到了

Unity3d利用A*演算法實現模擬

這裡我先引用一篇詳細文章來介紹A*演算法文章內容如下簡易地圖 如圖所示簡易地圖, 其中綠色方塊的是起點 (用 A 表示), 中間藍色的是障礙物, 紅色的方塊 (用 B 表示) 是目的地. 為了可以用一個二維陣列來表示地圖, 我們將地圖劃分成一個個的小方塊.二維陣列在遊戲中的應

js實現A*演算法

js使用canvas繪製介面。 定義兩個類:Node儲存點及A*演算法中的F=G+H值;Point。 /** * 節點 * p : 節點對應的座標 * pn : 節點的父節點 * g : A*-g * h : A*-h */ function Node(p,

A*演算法

#include <stdio.h>#include <stdlib.h>#define hello printf("hello\n");#define hi printf("hi\n");typedef struct NODE node;typede

Unity3D A* 演算法

筆者介紹:姜雪偉,IT公司技術合夥人,IT高階講師,CSDN社群專家,特邀編輯,暢銷書作者,國家專利發明人;已出版書籍:《手把手教你架構3D遊戲引擎》電子工業出版社和《Unity3D實戰核心技術詳解》電子工業出版社等。A*尋路演算法通常是應用於大型網路遊戲中,A*演算法通常應

Unity3d 實現 A * 演算法

原理A* 演算法是一種啟發式搜尋演算法,通過代價函式f = g+h,A*演算法每次查詢代價最低的點作為搜尋點,並更新搜尋節點列表。最終搜尋到目標位置。需要定義兩個列表 (Open和Closed列表):    private List<Tile> openList

A*演算法淺析

http://blog.csdn.net/yiyikela/article/details/46134339 最近剛接觸A*尋路演算法,聽說是一種比較高效的自動尋路的演算法,當然,事實也正是如此,這麼好的東西,自然是要收入囊中的,說不定什麼時候也能派上用場呢。為了學習這