演算法 A 尋路 視覺化

2021-09-10 21:44:39 字數 3826 閱讀 4438

如下圖 【尋路圖a】

使用a*演算法,需要將地圖抽象成乙個個方塊,藍色代表不可以動【牆】,黃色為起始點,紅色為目標點。其地圖的二維座標如圖所示,每乙個單位為1公尺

a*的基本公式為 f(n)=g(n)+h(n)

f:初始狀態到目標狀態n的代價估計【起始點到n的代價估計】

g:狀態空間中初始狀態到n的實際代價【n為中間某點,n到其parent的實際距離,n為parent的最小f所得】

h:從狀態n到目標狀態最佳路徑的估計代價【n到b的,x之差的絕對值與y之差的絕對值 之和】

演算法的基本思路

首先我們有乙個起始點,乙個目標點,還有一些牆,

並宣告乙個開啟【開啟列表】乙個【關閉列表】

【開啟列表】:當前待判斷點,

【關閉列表】:已經判斷過的點,不再參與尋路搜尋計算

1.開始時我們把起始點加入開啟列表,然後獲取起始點周圍所有可達到的點,將它們的parent設定為起始點,然後分別計算它們的fgh值,並把這些點加入開啟列表中,最後將起始點從開啟列表中移除,再加入關閉列表。

2.接著遍歷開始列表,尋找開始列表中f(到達目標點的預計代價)值最小的點,對此點進行如下操作

將此點加入關閉列表並從開始列表中移除

尋找此點周圍所有【按你自己的規則】【可達到的點】,並移除已經加入關閉列表中的部分,然後計算這些新點的fgh值,這裡需要重點注意的是更新parent的操作!

每個【可達到的點】都有自己的fgh,每次計算完乙個【可達到的點】的g值後,重新計算下此點到該【可達到的點】的g值,比較這兩個g值,若後者較小,這更新當前【可達到的點】的parent為此點

當此點所有【可達到的點】計算完成後,重複2,重新遍歷【開啟列表】尋找f值最小的點,並標記為此點,

終止的條件就是

1.開啟列表為空:目標點無法到達

2.開啟列表中包含目標點:已經到達

對於結果,我們每乙個點都計算出了其最小代價的parent,我們根據目標點的parent依次向上尋找直到起始點,即為最佳路徑

舉乙個**示例如下:【by siki】

每個路點繫結如下point

public class point

public float f

public float g

public float h

public int x

public int y

public bool iswall

public point(int x,int y,point parent=null) ;

listcloselist = new list;

openlist.add(start);

while (openlist.count > 0) ;

//不是牆,加入集合

if (down != null && down.iswall == false) {

list.add(down);

if (up != null && up.iswall == false) {

list.add(up);

if (left != null && left.iswall == false) {

list.add(left);

if (right != null && right.iswall == false) {

list.add(right);

//不是牆,且沒有障礙物阻攔,加入集合

if (upleft != null && upleft.iswall == false && left.iswall == false && up.iswall == false) {

list.add(upleft);

if (upright != null && upright.iswall == false && up.iswall == false && right.iswall == false) {

list.add(upright);

if (downleft != null && downleft.iswall == false && down.iswall == false && left.iswall == false) {

list.add(downleft);

if (downright != null && downright.iswall == false && down.iswall == false && right.iswall == false) {

list.add(downright);

return list;

去除已經處於關閉列表中的 周圍可到達點

private void pointsfilter(listsrc,listcloselist) {

foreach (point p in closelist) {

if (src.contains(p)) {

src.remove(p);

尋找開啟列表中 f值最小的點

private point findminfofpoint(listopenlist) {

float f = float.maxvalue;

point temp = null;

foreach (point p in openlist) {

if (p.f < f) {

temp = p;

f = p.f;

return temp;

//計算f值

private void calcf(point now,point end) {

//f=g+h

float h = mathf.abs(end.x - now.x) + mathf.abs(end.y - now.y);

float g = 0;

if (now.parent == null) {

g = 0;

else {

g=vector2.distance(new vector2(now.x, now.y), new vector2(now.parent.x, now.parent.y)) + now.parent.g;

float f = g + h;

now.f = f;

now.g = g;

now.h = h;

//計算g值

private float calcg(point now,point parent) {

return vector2.distance(new vector2(now.x, now.y), new vector2(parent.x, parent.y)) + parent.g;

列印結果

private void showpath(point start,point end) {

point temp = end;

while (true) {

debug.log(temp.x + " " + temp.y);

if (temp.parent == null) {

break;

temp = temp.parent;

最後開啟演算法

void start() {

initmap();

point start = map[2, 3];

point end = map[6, 3];

findpath(start, end);

showpath(start, end);

執行後列印結果如下:6 3,6 2,5 1,4 1,3 1,3 2,2 3

迷宮尋路(A星尋路演算法)

題目 假設我們有乙個7 5大小的迷宮,如下圖所示,綠色格仔表示起點,紅色的格仔表示終點,中間的3個深灰色格仔表示障礙物。請找到一條從起點到終點最短的路徑。解題思路 需要引入兩個集合和乙個公式,如下 具體步驟 把起點放入openlist 檢查openlist中是否有值,如果沒有則無法到達終點,結束尋路...

A 尋路演算法

問題 由於遊戲中尋路出了個小問題 玩家尋路到乙個死角後在那邊不停的來回跑,就是無法越過障礙物,就研究了下a 尋路演算法以解決這個問題 研究了幾天,自己寫了個demo這裡給出總結 原理 a 演算法給出的是權值最優的路徑而不是最短路徑 權值有f g h來表示 啟發式函式如下 f p g p h p h值...

A 尋路演算法

a 演算法是靜態環境下求最短路徑的不二之選,由於是啟發式搜尋,比dijkstra 深搜廣搜要快的多啦。a 也算是我第一次接觸的移動機械人演算法,csdn上的科普文章也不少,但我作為乙個機械的小白,實現出來還是小有成就感滴。今天抽空和大家分享一下原始碼,開發環境win7 64 opengl vs201...