青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

關(guān)于A*算法實(shí)用性優(yōu)化的個(gè)人想法

林 偉 2001.12

  這里的A*優(yōu)化只是針對(duì)網(wǎng)上一些關(guān)于A*算法介紹的文章來寫的,至于我接觸過的A*代碼可能都算不上專業(yè)級(jí)別因此我從這些代碼開始優(yōu)化也只是覺得這些代碼的優(yōu)點(diǎn)在于說明算法,而在效率與實(shí)用性方面就有些欠缺。

  A*是啟發(fā)試搜索加動(dòng)態(tài)規(guī)劃。具體實(shí)現(xiàn)依靠?jī)蓚€(gè)隊(duì)列Open隊(duì)列和Close隊(duì)列。從一點(diǎn)開始探走幾個(gè)相鄰的格子如果可以移動(dòng)且當(dāng)前移動(dòng)為起點(diǎn)到哪個(gè)格子的歷史最佳方法則把那個(gè)格子按照估價(jià)值從小到大插入Open隊(duì)列里面,幾個(gè)方向試探結(jié)素后取出估價(jià)值最小的節(jié)點(diǎn)放入Close再?gòu)倪@里開始試探幾個(gè)相鄰的方向同樣放入Open隊(duì)列里面,放入Open的條件是1.這步在地圖上面是可以移動(dòng)的,2.這步所在節(jié)點(diǎn)在Open里面并不存在,3.從起點(diǎn)到這步的實(shí)際距離比這點(diǎn)的歷史最小距離還短滿足這三個(gè)條件就把節(jié)點(diǎn)放入Open隊(duì)列。具體的算法網(wǎng)友們已經(jīng)描述的再清楚不過了大致算法如下:

findpath()
{
?? 把S點(diǎn)加入Open隊(duì)列(按該點(diǎn)到E點(diǎn)的距離排序+走過的步數(shù)從小到大排序)
?? 1、排序隊(duì)列Open隊(duì)列中距離最小的第一個(gè)點(diǎn)出列,并保存入Close隊(duì)列中
?? 2、從出列的點(diǎn)出發(fā),分別向4個(gè)(或8個(gè))方向中的一個(gè)各走出一步
?? 3、并估算第2步所走到位置到目標(biāo)點(diǎn)的距離,并把該位置按估價(jià)距離從小到大排序后并放入Open隊(duì)列中
?? 4、如果該點(diǎn)從四個(gè)方向上都不能移動(dòng),則把該點(diǎn)從Close隊(duì)列中刪除
?? 5、回到第一點(diǎn),直到找到E點(diǎn)則結(jié)束
?? 從目標(biāo)點(diǎn)回溯樹,直到樹根則可以找到最佳路徑,并保存在path[]中
}
具體實(shí)現(xiàn)和詳細(xì)算法可以看這段代碼(sort_queue和store_queue是open和close隊(duì)列)

  我覺得要使它可以勝任即時(shí)戰(zhàn)略游戲第一點(diǎn)要改的就是規(guī)定搜尋的規(guī)模,即限制close_queue的大小,一旦超過大小而并沒有到達(dá)終點(diǎn),則取一個(gè)搜尋過的最接近終點(diǎn)的點(diǎn)(從它到終點(diǎn)的估價(jià)距離最短)作為搜索的終點(diǎn)。二一旦Open隊(duì)列空了無法取出節(jié)點(diǎn)時(shí)搜索結(jié)束沒有找到終點(diǎn),此時(shí)還是按照上面的方法找一個(gè)最接近終點(diǎn)的點(diǎn)代替終點(diǎn)

  
  這樣搜索就不會(huì)漫無邊際地進(jìn)行下去了。上面的程序大家稍微觀察就會(huì)發(fā)現(xiàn)幾處影響速度的致命地方,啟發(fā)試搜索是不變的,而看程序每次加入取出兩個(gè)隊(duì)列時(shí)都要進(jìn)行繁瑣的內(nèi)存分配,這是項(xiàng)耗費(fèi)時(shí)間的工作,其次需要檢查是否在隊(duì)列中,這點(diǎn)也是很慢的,最后就是保存動(dòng)態(tài)規(guī)劃數(shù)據(jù)(歷史最短距離)的數(shù)組進(jìn)行還原,并且每次尋路都要還原若大的數(shù)組,這是無法接受的。

  我所說的優(yōu)化是從數(shù)據(jù)結(jié)構(gòu)入手解決上面的問題讓Open/Close兩隊(duì)列處理時(shí)不再涉及內(nèi)存分配問題,首先建立一個(gè)與地圖上面每個(gè)節(jié)點(diǎn)一一對(duì)應(yīng)的節(jié)點(diǎn)數(shù)組Node[maph][mapw];Node里面有一個(gè)指針Next和Father,Next指相所在隊(duì)列的下一個(gè)節(jié)點(diǎn),F(xiàn)ather指向它的父節(jié)點(diǎn)。由于Open/Close兩隊(duì)列不可能出現(xiàn)一個(gè)節(jié)點(diǎn)在某個(gè)隊(duì)列同時(shí)出現(xiàn)兩次的情況因此Open隊(duì)列描述時(shí)只要讓它指向一個(gè)節(jié)點(diǎn)地址&Node[y][x]然后讓Node[y][x]的Next指向隊(duì)列下一個(gè)節(jié)點(diǎn),如果沒有節(jié)點(diǎn)則這點(diǎn)的Next為NULL,同樣的道理Close也是這樣描述的如此來看每次搜尋的時(shí)候就不必內(nèi)存分配了,插入節(jié)點(diǎn)(x,y)時(shí)只要改動(dòng)Node[maph][mapw]上面的數(shù)據(jù)和Open/Close兩個(gè)指針就輕松搞定了見程序的AddToOpenQueue等幾個(gè)函數(shù)。在初始化的時(shí)候一次性分配**Node為Node[maph][mapw](TAstarNode的定義如下表)Open/Close為兩個(gè)TAstarNode指針以后就不再分配內(nèi)存了,初始化讓Open/Close都等于NULL在Open中加入節(jié)點(diǎn)(x,y)就按照普通連表的方法插入&Node[y][x]換而言之,就是讓Open/Close指向Node[maph][mapw]中的某個(gè)元素,然后這個(gè)元素又指向下一個(gè)元素形成鏈表,由于算法中每次加入Open/Close的節(jié)點(diǎn)前檢查如果存在了就不再加入因此Open/Close不會(huì)有重復(fù)的元素。

struct TAstarNode
{
 ADWORD Pos;     // ((y<<16)|x)初始化時(shí)設(shè)定以后不變
 short ActualCost;  // 保存從起點(diǎn)到該節(jié)點(diǎn)的實(shí)際開銷
 short EstimateCost; // 保存此點(diǎn)的估價(jià)開銷由JudgeCost函數(shù)提供初始化為MAX
 TAstarNode *Father; // 此點(diǎn)的父節(jié)點(diǎn)
 TAstarNode *Next;  // 在Open或者Next鏈表中的下一個(gè)節(jié)點(diǎn)
 char Modified;    // 1位該節(jié)點(diǎn)是否被修改過,2/3位代表是否于Open/Close表
} **Node,*Open,*Close; // Node[maph][mapw]和Open/Close隊(duì)列

  右圖為Node[h][w]和Open表的示范,初始化Node時(shí)設(shè)置EstimateCost為MAX另外需要一個(gè)變量描述改動(dòng)狀態(tài)(Modified),如果改動(dòng)過最佳記錄則狀態(tài)第0位為1,如果在Open隊(duì)列中則地1位為1,如果在Close中則第2位為1那么只要通過位運(yùn)算就可以知道節(jié)點(diǎn)和隊(duì)列的關(guān)系了,另外用一個(gè)數(shù)組來記錄修改過最佳距離的節(jié)點(diǎn)位置,并且依據(jù)前面的狀態(tài)變量來判斷如果以前已經(jīng)記錄過就不再記錄了,當(dāng)路徑搜索完以后就根據(jù)這個(gè)數(shù)組來還原數(shù)據(jù)了。

  請(qǐng)看右邊的搜索試列圖,可以簡(jiǎn)單看出OPEN隊(duì)列在插入/刪除時(shí)并不需要內(nèi)存分配而只要改變其指針和Node[h][w]中節(jié)點(diǎn)的Next指針就行了。這是激動(dòng)人心的提高,

  

?

?

?

?

?

?

  有了前面兩段的優(yōu)化,路徑算法已經(jīng)省去了許多不必要的工序了,再看下實(shí)用性方面,首先判斷地圖是否可以移動(dòng)不要在算法中直接判斷而最好設(shè)置一個(gè)虛函數(shù)MoveAble(x,y)來實(shí)現(xiàn)(程序中我用函數(shù)指針代替),因?yàn)樵谟螒蛑心硥K地圖對(duì)于地面單位和空中單位還有水下單位可以移動(dòng)的情況都不同因此直接操作地圖元素并不是明智的選擇,再者估價(jià)函數(shù)JudgeCost(x,y)也應(yīng)該設(shè)置成虛函數(shù)或者函數(shù)指針來實(shí)現(xiàn),畢竟求估價(jià)值的方法很靈活,這里不能限制死了。

  還有每次尋路搜索哪些方向呢?用DirMask來描述0-7位代表從上開始順時(shí)針一圈的八個(gè)方向情況,0代表不搜索,1代表搜索,那么四個(gè)方向搜索可以用0x55(1010101b)來代替,八個(gè)方向可以用0xff來設(shè)定,如此一來你可以設(shè)定只進(jìn)行搜索3個(gè)方向的尋路,這樣可以滿足一些簡(jiǎn)單的尋路任務(wù)了,比如RPG中NPC敵人的移動(dòng)就可以這樣來設(shè)定。最后就是范圍問題的設(shè)定了,Open表的最大大小可以設(shè)置為100-200(四個(gè)方向)或200-300(八個(gè)方向)而Close表的大小即處理節(jié)點(diǎn)的最多數(shù)目可以設(shè)置成(MapH*MapW)/16這樣的設(shè)定在士兵走入一個(gè)桶形地形時(shí)并不會(huì)花費(fèi)很大的開銷去尋找通路,而是走到桶形地形的尖端。其具體值可以適當(dāng)調(diào)整,當(dāng)然數(shù)值越大搜索就越廣,開銷也就越大(MapH*Map)/16這個(gè)數(shù)值我自己感覺比較接近星際的尋路特點(diǎn)

  其它優(yōu)化,由于Open隊(duì)列中的數(shù)據(jù)全部是連表插入排序的,當(dāng)數(shù)據(jù)多時(shí)效率并不會(huì)見得高。這時(shí)如果還要繼續(xù)優(yōu)化手段也很多,比如建立Hash散列表,或者用二叉樹來代替連表排序,大家可以參考前導(dǎo)公司的寫的A*代碼里面就用了散列表這點(diǎn)很優(yōu)秀,但它任然擺脫不了大量的內(nèi)存分配/釋放。因此此處我覺得不怎么高明。

  到是估價(jià)值的計(jì)算方法很多,但是寫的好壞也關(guān)系到搜索的規(guī)模:坐標(biāo)差之絕對(duì)值乘加權(quán)值求和,平方和開方還有些怪的呢,可以看看前導(dǎo)的代碼估價(jià)函數(shù)是怎么寫的。我看到網(wǎng)上有文章說當(dāng)前節(jié)點(diǎn)到終點(diǎn)的估計(jì)距離不能比實(shí)際距離大,說什么才能叫做A*算法,否則只能叫A算法(人工智能書上說的),因?yàn)椴灰欢ㄊ亲疃搪窂剑呛堑侨绻皇菨M足估價(jià)值小于真實(shí)值也不一定就可以找到最短路徑故暫且不論,先看JudgeCost的意義--使搜索更靠近終點(diǎn),勢(shì)必減小JudgeCost將會(huì)增加搜索的寬度及規(guī)模,增加JudgeCost則使搜索跟快地向終點(diǎn)靠攏。下面是使用不同估價(jià)函數(shù)的對(duì)比:

JudgeCost=abs(dx)+abs(dy)
JudgeCost=abs(dx),abs(dy)加權(quán)求和

  上圖兩種估價(jià)函數(shù)的求法,星號(hào)是路徑點(diǎn)是搜索過的節(jié)點(diǎn),當(dāng)JudgeCost大于真實(shí)值時(shí)從一個(gè)節(jié)點(diǎn)出發(fā)算法更愿意搜索一個(gè)靠終點(diǎn)近的點(diǎn),換言之JudgeCost越大算法就越買力向終點(diǎn)靠攏,從左右兩副圖可以清楚看到(點(diǎn)擊放大)。所以我們使用坐標(biāo)差加權(quán)求和來處理或者直接求和乘與一個(gè)數(shù)字(比如8)在地形復(fù)雜的時(shí)候就更加顯出這種方法的實(shí)用性了,良種式子的規(guī)模差距還要比上圖嚴(yán)重的多。所以通用地用加權(quán)求和dx=abs(x-endx),dy=abs(y-endy);if (dx>dy) result =10*dx+6*dy; else result=10*dy+6*dx;就是這個(gè)意思,所用的乘10和乘6是試驗(yàn)證明比較好用的數(shù)字了,如此一來搜索的規(guī)模就被控制得又減小了,是不可忽視的。

  還有幾點(diǎn)要注意的,集體尋路要采用跟隨政策,共用一條路徑,中途遇到移動(dòng)物分三步走:嘗試加入一個(gè)斜方的路徑節(jié)點(diǎn)看是否可以饒過;不能就等待移動(dòng)物體自己走開;到了時(shí)間不走再另外搜尋路徑,大場(chǎng)景要預(yù)先設(shè)定一些路徑節(jié)點(diǎn)中轉(zhuǎn)站再進(jìn)行遠(yuǎn)距離搜索時(shí)可以大大提高效率,用方向保存路徑比用坐標(biāo)保存節(jié)省至少1/4的空間。。。。碰到敵人部隊(duì)就開槍,自己部隊(duì)則可以不走了,或者發(fā)送兩條指令給擋住路的士兵的指令隊(duì)列1.移開當(dāng)前位置并等待;2.回到當(dāng)前位置,這樣可以產(chǎn)生一個(gè)一個(gè)順序讓路的精彩效果,紅警里面早已有實(shí)現(xiàn):-)

  講遠(yuǎn)了,那是行軍問題了,前段時(shí)間給一個(gè)高中生輔導(dǎo)NOI復(fù)賽,那小子竟然在講到廣度優(yōu)先時(shí)問了路徑算法,一時(shí)興起就寫了這篇文章以及一段三百多行的程序,順便供大家參考:-) 一家之言,歡迎來信討論: skywindt@yeah.net

Copyright LinWei 2001/12/19

posted on 2006-06-19 21:27 楊粼波 閱讀(334) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩亚洲精品在线| 一区二区免费在线播放| 美女在线一区二区| 欧美一区二区三区四区夜夜大片| 亚洲视频你懂的| 午夜精品福利视频| 久久精品一区四区| 欧美.日韩.国产.一区.二区| 久久久夜精品| 欧美性jizz18性欧美| 欧美激情精品久久久久久免费印度 | 亚洲美女精品久久| 亚洲视频综合在线| 久久成人免费网| 蜜桃av噜噜一区| 亚洲日韩欧美视频| 夜夜嗨av一区二区三区中文字幕 | 欧美中文字幕第一页| 久久一区二区精品| 欧美日韩在线播放一区二区| 国产精品99一区二区| 国产综合精品| 一本久久知道综合久久| 欧美一区二区久久久| 欧美大片18| 亚洲欧美激情四射在线日| 久久亚洲综合色| 国产精品久久久久影院色老大 | 国产精品免费视频观看| 激情婷婷欧美| 亚洲欧美精品伊人久久| 欧美粗暴jizz性欧美20| 亚洲一区二区av电影| 麻豆国产精品va在线观看不卡| 欧美午夜不卡视频| 亚洲欧洲一区二区三区| 久久午夜av| 亚洲欧美国产毛片在线| 欧美理论大片| 亚洲三级视频| 免费欧美视频| 久久国产婷婷国产香蕉| 国产精品家教| 亚洲午夜在线观看| 亚洲国产另类 国产精品国产免费| 亚洲欧美怡红院| 欧美午夜女人视频在线| 亚洲精品在线视频观看| 久久青草欧美一区二区三区| 亚洲尤物精选| 国产精品多人| 亚洲一区二区综合| 亚洲精品免费一二三区| 欧美顶级艳妇交换群宴| 最新国产成人在线观看| 国产精品亚洲人在线观看| 欧美久久久久| 99国产精品久久久久久久成人热| 快播亚洲色图| 久久精品一区二区三区不卡| 国产精品午夜av在线| 亚洲已满18点击进入久久| 亚洲精品中文字幕在线| 欧美精品二区| 一区二区三区欧美| 99在线|亚洲一区二区| 欧美日韩亚洲国产精品| 亚洲天堂第二页| 亚洲视频axxx| 国产欧美日韩91| 久久久久一区| 卡一卡二国产精品| 亚洲日产国产精品| 亚洲欧洲日韩在线| 欧美偷拍另类| 欧美一区二区三区电影在线观看| 亚洲天堂av在线免费| 国产农村妇女精品一区二区| 久久久7777| 欧美h视频在线| 亚洲一区二区三区在线| 午夜日韩在线观看| 亚洲国产日韩欧美综合久久| 亚洲精品久久视频| 国产精品午夜av在线| 久久午夜精品一区二区| 欧美国产精品专区| 午夜精品福利一区二区蜜股av| 欧美一区二区大片| 亚洲国产另类久久精品| 夜夜爽99久久国产综合精品女不卡 | 欧美风情在线| 亚洲一级高清| 久久九九免费| 99re这里只有精品6| 亚洲影音一区| 亚洲激情在线| 亚洲影院免费| 亚洲精品久久久蜜桃| 亚洲一区日韩| 亚洲狼人综合| 性感少妇一区| 一区二区三区精品| 久久久久综合一区二区三区| 亚洲天堂网在线观看| 久久精品视频99| 亚洲淫片在线视频| 欧美成人午夜视频| 久久久青草青青国产亚洲免观| 欧美伦理视频网站| 久久久91精品国产一区二区三区 | 91久久久久久久久| 亚洲三级电影全部在线观看高清 | 国产精品99久久久久久白浆小说| 午夜久久久久久| av成人免费在线| 久久男人av资源网站| 亚洲欧美激情四射在线日| 久久综合久久久| 久久久精品一区二区三区| 欧美精品免费看| 欧美国产日韩一区二区三区| 国产偷自视频区视频一区二区| 亚洲精品精选| 亚洲欧洲精品一区二区三区不卡 | 欧美日韩日韩| 欧美黑人在线观看| 激情一区二区三区| 欧美一区二区三区的| 欧美伊人久久久久久午夜久久久久| 欧美精品在线极品| 亚洲国产国产亚洲一二三| 好吊日精品视频| 久久高清免费观看| 久久久精品一区二区三区| 国产午夜精品福利| 欧美一级免费视频| 久久久久看片| 在线看日韩av| 欧美a级一区| 亚洲精品久久久久久久久久久久久 | 久久xxxx精品视频| 国产精品一区二区你懂得| 亚洲亚洲精品三区日韩精品在线视频 | 国产精品chinese| 99精品久久久| 亚洲欧美在线播放| 国产欧美日韩亚洲一区二区三区| 亚洲女同同性videoxma| 欧美一区二区三区视频免费| 国产精品中文字幕在线观看| 亚洲欧美另类久久久精品2019| 亚洲欧美国产高清va在线播| 国产精品久久久久久久7电影| 亚洲小视频在线观看| 久久精品99久久香蕉国产色戒| 国产欧美精品日韩| 久久久亚洲成人| 亚洲国产欧美国产综合一区 | 久热国产精品| 亚洲人成网站999久久久综合| 韩日欧美一区二区| 欧美激情四色| 99国产精品久久久久久久| 亚洲自拍偷拍麻豆| 黄色成人精品网站| 欧美成人精品一区二区三区| 日韩午夜激情av| 久久国产婷婷国产香蕉| 亚洲国产精品va| 国产精品成人播放| 久久精品国产亚洲一区二区| 91久久精品国产91久久| 亚洲综合精品四区| 亚洲国产乱码最新视频| 国产精品成人免费| 美女露胸一区二区三区| 亚洲一区二区三区中文字幕| 另类春色校园亚洲| 午夜精品区一区二区三| 亚洲黄网站黄| 国产一区在线看| 欧美日韩亚洲高清| 久久一本综合频道| 亚洲欧美精品在线| 亚洲人成亚洲人成在线观看图片| 久久国产精品久久久久久| 亚洲剧情一区二区| 极品中文字幕一区| 国产精品女主播| 欧美日韩精品免费观看视频完整| 久久精品视频亚洲| 亚洲在线观看免费视频| 亚洲人体大胆视频| 免费看成人av| 久久一日本道色综合久久| 亚洲摸下面视频| 一区二区日本视频| 亚洲久久一区| 日韩午夜一区|