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

牽著老婆滿街逛

嚴(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>
            亚洲国产欧美日韩| 欧美18av| 国产麻豆综合| 久久成人精品视频| 午夜在线成人av| 国产综合久久久久影院| 裸体素人女欧美日韩| 久久深夜福利免费观看| 亚洲国产精品成人一区二区 | 欧美一级欧美一级在线播放| 亚洲综合首页| 国内外成人免费激情在线视频网站 | 国产日韩亚洲欧美| 久久人人爽人人爽| 老司机成人在线视频| 99精品欧美一区二区三区| 亚洲视频 欧洲视频| 狠狠色丁香久久综合频道| 牛牛精品成人免费视频| 欧美日韩视频免费播放| 久久久久www| 欧美成人自拍| 欧美一区二视频| 免播放器亚洲一区| 亚洲欧美日韩精品| 开心色5月久久精品| 亚洲图片在线观看| 久久久久久尹人网香蕉| 亚洲午夜激情| 久久综合999| 性xx色xx综合久久久xx| 欧美va天堂| 久久人人九九| 国产精品久久久久久亚洲调教 | 洋洋av久久久久久久一区| 亚洲一区在线免费观看| 亚洲国产电影| 亚洲欧美资源在线| 夜夜爽www精品| 久久免费国产精品1| 亚洲欧美日韩国产中文在线| 欧美成人三级在线| 久久人人精品| 国产日韩一级二级三级| 一本色道久久88综合日韩精品| 欧美涩涩网站| 蜜臀久久久99精品久久久久久| 午夜亚洲性色福利视频| 欧美精品在线播放| 亚洲国产91色在线| 国产一级一区二区| 午夜天堂精品久久久久| 亚洲专区一区| 欧美三级免费| 91久久国产综合久久91精品网站| 精品福利av| 欧美一区二区私人影院日本| 香蕉乱码成人久久天堂爱免费| 欧美日韩在线精品一区二区三区| 亚洲黄一区二区三区| 亚洲东热激情| 米奇777超碰欧美日韩亚洲| 久久野战av| 精品动漫一区二区| 久久国产直播| 麻豆免费精品视频| 亚洲国产91| 欧美成人免费在线| 91久久综合亚洲鲁鲁五月天| 亚洲精品在线电影| 欧美激情麻豆| 亚洲麻豆国产自偷在线| 亚洲一区成人| 国产免费成人av| 欧美专区第一页| 免费成人av| 亚洲美女毛片| 国产精品久久久久久福利一牛影视| 亚洲永久免费精品| 久久精品国产一区二区三区免费看| 国产视频自拍一区| 久久久综合网| 91久久国产精品91久久性色| 亚洲婷婷综合久久一本伊一区| 国产精品人人爽人人做我的可爱 | 久久久精品国产免费观看同学| 国内精品写真在线观看| 免费不卡在线观看av| 91久久在线观看| 欧美一区二区视频网站| 一区二区三区在线免费视频| 欧美黑人多人双交| 亚洲欧美日本在线| 欧美承认网站| 午夜久久影院| 亚洲福利电影| 国产精品海角社区在线观看| 小处雏高清一区二区三区 | 久久精品国产亚洲aⅴ| 亚洲青涩在线| 国产欧美视频一区二区| 久久伊人亚洲| 亚洲视频高清| 欧美激情91| 欧美在线视频一区二区| 亚洲精品乱码| 国产亚洲精品久| 欧美激情中文字幕在线| 西瓜成人精品人成网站| 亚洲精品久久7777| 久久夜色精品国产亚洲aⅴ| 夜夜嗨一区二区| 亚洲国产天堂久久综合网| 国产精品热久久久久夜色精品三区| 免费在线观看一区二区| 国产精品久久777777毛茸茸| 久久久久综合网| 亚洲调教视频在线观看| 亚洲成色777777女色窝| 久久久久久久久综合| 亚洲综合精品四区| 亚洲精品在线看| 伊人久久亚洲美女图片| 国产精品天美传媒入口| 欧美精品一区二区三区蜜桃 | 欧美精品一区二区三区一线天视频 | 一区二区欧美激情| 亚洲成色777777女色窝| 国内免费精品永久在线视频| 国产精品日韩欧美| 国产精品porn| 欧美日韩一区二区在线| 欧美韩国日本综合| 蜜臀av性久久久久蜜臀aⅴ四虎| 久久av二区| 欧美一级久久久| 欧美一级播放| 久久爱另类一区二区小说| 亚洲女同同性videoxma| 一区二区三区免费观看| 99热这里只有精品8| 亚洲区免费影片| 亚洲精品视频免费在线观看| 最新亚洲电影| 亚洲欧洲在线看| 最新日韩中文字幕| 99亚洲一区二区| 亚洲深夜福利视频| 亚洲欧美日韩一区二区在线| 午夜精彩视频在线观看不卡| 欧美一区91| 久久亚洲午夜电影| 欧美jizzhd精品欧美巨大免费| 欧美成人高清| 欧美日韩国产一区二区三区地区| 欧美精品日韩一本| 欧美午夜精品久久久久久孕妇 | 国产精品国产精品国产专区不蜜| 国产精品99一区| 国产伦精品一区二区三区照片91| 国产欧美一区二区三区国产幕精品 | 蜜臀99久久精品久久久久久软件| 麻豆av一区二区三区久久| 欧美成人精品h版在线观看| 欧美黄色成人网| 欧美午夜性色大片在线观看| 国产精品有限公司| 一区在线影院| 日韩亚洲一区二区| 欧美一区二区三区啪啪| 久久免费黄色| 亚洲精品综合精品自拍| 亚洲一区美女视频在线观看免费| 香蕉久久久久久久av网站| 久久久久免费| 国产精品成人观看视频免费| 国产在线观看精品一区二区三区| 亚洲人成久久| 久久精品91| 亚洲三级电影全部在线观看高清| 亚洲图片欧美一区| 久久免费午夜影院| 欧美大片网址| 一区二区三区四区五区在线| 亚洲看片免费| 性视频1819p久久| 欧美理论电影在线观看| 国产日韩一区二区三区在线播放 | 亚洲电影在线观看| 午夜精品一区二区三区电影天堂| 久久蜜桃资源一区二区老牛 | 99精品国产在热久久婷婷| 久久爱www久久做| 国产精品久久久久久久电影| 亚洲电影在线看| 久久久久久久久久久久久女国产乱| 亚洲人体大胆视频| 另类激情亚洲| 韩国v欧美v日本v亚洲v| 午夜亚洲性色福利视频|