從頭理解JPS尋路算法

文末有新版描述

JPS(jump point search)概述

本文的思路受到博客:http://blog.sina.com.cn/s/blog_4a5c75d40102wo5l.html
和論文:http://www.doc88.com/p-6099778647749.html的啟發(fā)和借鑒凰狞。
JPS(jump point search)算法實(shí)際上是對(duì)A尋路算法的一個(gè)改進(jìn),即在擴(kuò)展搜索節(jié)點(diǎn)時(shí),提出了更優(yōu)化的策略沛鸵,A在擴(kuò)展節(jié)點(diǎn)時(shí)會(huì)把節(jié)點(diǎn)所有鄰居都考慮進(jìn)去泪勒,這樣openlist中點(diǎn)的數(shù)量會(huì)很多闪盔,搜索效率較慢瑟俭。JPS算法通過(guò)尋找跳點(diǎn)的方式违寞,排除了大量不感興趣的點(diǎn)贞瞒,減少了openlist中搜索的點(diǎn)的數(shù)量,速度大大提高趁曼。

圖例拆解JPS過(guò)程

自然鄰居:如圖所示军浆,紅色塊是自然鄰居。
被迫鄰居:點(diǎn)x的8個(gè)鄰居中有障礙挡闰,n不是x的自然鄰居乒融,且x的父親節(jié)點(diǎn)p(x)經(jīng)過(guò)x到達(dá)n的距離代價(jià)比不經(jīng)過(guò)x到達(dá)的n的任意路徑的距離代價(jià)小,則稱n是x的被迫鄰居摄悯。這其中隱含了對(duì)p(x)的描述赞季,最完整的表述應(yīng)該是,n是x在x的父親節(jié)點(diǎn)是p(x)的情況下的被迫鄰居奢驯。見圖示申钩。
跳點(diǎn):基于點(diǎn)x(當(dāng)前點(diǎn)為x),且搜索方向?yàn)閐(斜向或水平或垂直)叨橱,點(diǎn)y滿足一下三個(gè)條件之一,那么y就是跳點(diǎn)断盛。
a.節(jié)點(diǎn)y是終點(diǎn)罗洗,那么節(jié)點(diǎn)y是跳點(diǎn)。
b.節(jié)點(diǎn)y至少有一個(gè)被迫鄰居钢猛,那么節(jié)點(diǎn)y是跳點(diǎn)伙菜。
c.如果d是斜向搜索,如果節(jié)點(diǎn)y的水平或垂直方向上有滿足條件a命迈,b的點(diǎn)贩绕,那么節(jié)點(diǎn)y是跳點(diǎn)。注:節(jié)點(diǎn)y的水平或垂直方向是斜向向量的拆解壶愤,比如向量d=(1,1)淑倾,那么水平方向則是(1,0),并不會(huì)往左搜索征椒,只會(huì)看右邊娇哆,如果向量d=(-1,-1),那么水平方向是(-1,0),只會(huì)搜索左邊碍讨,不看右邊治力,其他同理。

紅色塊為自然鄰居勃黍,黑色塊為障礙物宵统,綠色塊為被迫鄰居

水平(垂直)搜索:如圖右邊部分描述,點(diǎn)1和4如果經(jīng)過(guò)x到達(dá)覆获,還不如從點(diǎn)p(x)到達(dá)马澈,所以不用考慮點(diǎn)1,4,同理繼續(xù)向右搜索時(shí)锻梳,點(diǎn)2,5和點(diǎn)3,6箭券,都是類似的情況,直到遇到黑色的障礙疑枯,沒有發(fā)現(xiàn)感興趣的點(diǎn)辩块,x處水平方向搜索完成,垂直方向搜索類似荆永。如圖左邊部分描述废亭,在點(diǎn)x處向右搜索至點(diǎn)y時(shí),點(diǎn)y有一個(gè)強(qiáng)迫鄰居(點(diǎn)7)具钥,因此y是從點(diǎn)x處沿水平方向搜索的一個(gè)跳點(diǎn)豆村,需要將y加入到openlist中。水平搜索結(jié)束骂删。

水平(垂直)搜索

對(duì)角搜索:斜向搜索時(shí)掌动,需要先在當(dāng)前點(diǎn)的水平和垂直方向搜索一下,看能否找到感興趣的點(diǎn)宁玫,如果找到粗恢,則將當(dāng)前點(diǎn)加到openlist,結(jié)束斜向搜索欧瘪,如果找不到眷射,則繼續(xù)斜向多走一步,繼續(xù)佛掖,直到找到感興趣的點(diǎn)或者斜向方向遇到障礙妖碉。

斜向搜索的兩種情況

一條完整路線的搜索過(guò)程:

完整搜索路線,起點(diǎn)S芥被,終點(diǎn)T欧宜,黃色框是在過(guò)程中加入openlist的點(diǎn),紅色箭頭嘗試搜索返回失敗拴魄,綠色箭頭成功返回感興趣點(diǎn)鱼鸠。

搜索算法:

Algorithm 1 Identify Successors

Require: x:current node, s:start, g:goal
1: successor(x) <- empty
2: neighbours(x) <- prune(x, neighbours(x))
3: for all n in neighbours(x) do
4:__n <- jump(x, direction(x,n),s,g)
5:__add n to successor(x)
6:return successor(x)

Algorithm 2 Function Jump

Require: x:initial node, d:direction, s:start, g:goal
1: n <- step(x, d)
2: if n is an obstacle or is outside the grid then
3:__return null
4: if n = g then
5: return n
6: if exists n' belongs to neighbours(n) s.t. n' is forced then
7:__return n
8: if d is diagonal then
9: __for i in {1,2} do
10: ____if jump(n,di,s,g) is not null then return n
11: return jump(n,d,s,g)

A*與JPS對(duì)比

下面兩張對(duì)比圖猛拴,摘自上面的論文,可以看出蚀狰,JPS算法實(shí)在優(yōu)秀愉昆。

A*與JPS擴(kuò)展節(jié)點(diǎn)對(duì)比
各尋路算法路徑長(zhǎng)度和搜索時(shí)間

代碼

github鏈接

2020-5-15 重寫版本

  1. 強(qiáng)迫鄰居(被迫鄰居)定義
自然鄰居和強(qiáng)迫鄰居

上圖中紅色塊為節(jié)點(diǎn)x,基于前節(jié)點(diǎn)為P(x)的情況下的自然鄰居節(jié)點(diǎn)麻蹋。而被迫鄰居則是圖中綠色的方塊(其對(duì)稱情況未畫出)跛溉。x被迫鄰居包含三層隱藏含義:首先被迫鄰居的位置是基于P(x)、x扮授、阻擋塊的相對(duì)關(guān)系定的芳室,如第三個(gè)圖所示,如果第三個(gè)圖中刹勃,P(x)的位置在節(jié)點(diǎn)6的位置堪侯,那么綠色方塊就不是x的被迫鄰居了。其次荔仁,被迫鄰居一點(diǎn)是考察非自然鄰居的節(jié)點(diǎn)伍宦。最后被迫鄰居一定是P(x)經(jīng)過(guò)x到達(dá)才能取得最短路徑的點(diǎn)。

注意:接下來(lái)的討論都基于一個(gè)前提:斜向可以通過(guò)乏梁,即如上圖4中次洼,P(x)和x可以直達(dá),x和綠色塊可以直達(dá)遇骑。
有些算法或者游戲?qū)嵺`中卖毁,這種斜向穿過(guò)是不允許的,如P(x)->x落萎,這好比人物穿過(guò)了墻角亥啦,在游戲內(nèi)是不可以接受的,應(yīng)該走P(x)->6->x练链。

  1. 跳點(diǎn)定義
    滿足如下條件的點(diǎn)視為跳點(diǎn):
    i. 節(jié)點(diǎn)y是起點(diǎn)或終點(diǎn)翔脱。
    ii. 節(jié)點(diǎn)y在當(dāng)前搜索方向的前提下,有強(qiáng)迫鄰居兑宇。
    iii. 當(dāng)前搜索方向是斜向碍侦,且在y節(jié)點(diǎn)處粱坤,經(jīng)過(guò)該斜向的水平分量或垂直分量方向移動(dòng)可以找到跳點(diǎn)隶糕,那么當(dāng)前節(jié)點(diǎn)y是跳點(diǎn)。

  2. 搜索規(guī)則
    i. 在搜索時(shí)站玄,如果直線和斜向都能通過(guò)枚驻,先在直線方向搜索跳點(diǎn),然后在斜向上搜索跳點(diǎn)株旷。
    ii. n是x的鄰居再登,若有從P(x)到n且不經(jīng)過(guò)x的路徑尔邓,且該路徑小于等于從P(x)經(jīng)過(guò)x到達(dá)n的路徑的長(zhǎng)度,那么走到x后下一個(gè)節(jié)點(diǎn)不會(huì)走到n锉矢。
    iii. 只有跳點(diǎn)才會(huì)被加入openlist里梯嗽,最后找出來(lái)的最短路徑也是由跳點(diǎn)組成。

一次完整的搜索過(guò)程

JPS搜索過(guò)程

起點(diǎn)S沽损,終點(diǎn)T灯节,黑色塊為阻擋黃色塊為跳點(diǎn),紅色箭頭是搜索方向绵估,但是沒有找到跳點(diǎn)炎疆,綠色箭頭表示找到跳點(diǎn)。橫坐標(biāo)A-N国裳,縱坐標(biāo)1-10形入。

起始位置S,將A10加入openlist里缝左,開始算法流程亿遂。
從openlist里取出代價(jià)最小的節(jié)點(diǎn)(現(xiàn)在為S),當(dāng)前節(jié)點(diǎn)沒有方向盒使,所以需要搜索8個(gè)方向崩掘,只有右上方B9點(diǎn)是跳點(diǎn)。因?yàn)楦鶕?jù)跳點(diǎn)定義iii少办,斜向搜索時(shí)苞慢,需要在兩個(gè)分量方向查找跳點(diǎn),右方是墻壁英妓,略過(guò)挽放,上方B8點(diǎn)有強(qiáng)迫鄰居點(diǎn)C7,所以B8是跳點(diǎn)(根據(jù)跳點(diǎn)定義ii)蔓纠,所以B9是跳點(diǎn)辑畦。將B9加入openlist里。A10處理完后腿倚,將其從openlist中移除纯出,加入closelist里。

從openlist中取出B9點(diǎn)敷燎,該點(diǎn)的父親是S暂筝,所以搜索方向?yàn)橛倚鄙希枰谟倚鄙嫌补幔曳交澜螅戏剿阉魈c(diǎn),只有B8滿足要求饭豹,將B8加入openlist鸵赖。處理完B9點(diǎn)將其移到closelist务漩。

從openlist取出B8點(diǎn),該點(diǎn)搜索方向?yàn)樯纤剩珺8有被鄰居C7點(diǎn)饵骨,在斜上方搜索跳點(diǎn),可以看出D8是C7的被迫鄰居茫打,所以C7是跳點(diǎn)宏悦,B8處繼續(xù)向上搜索結(jié)束。

從openlist中取出C7點(diǎn)包吝。需要搜索右上饼煞,右,上三個(gè)方向诗越。水平搜索時(shí)發(fā)現(xiàn)被迫鄰居D8砖瞧,加入openlist。右上搜索時(shí)發(fā)現(xiàn)跳點(diǎn)G3(因其在上方搜索時(shí)發(fā)現(xiàn)具有被迫鄰居節(jié)點(diǎn)的G2)嚷狞,將G3加入openlist块促。C7點(diǎn)處理結(jié)束。

取出G3點(diǎn)(為啥是G3床未,而不是D8點(diǎn)呢竭翠,因?yàn)閺目偞鷥r(jià)來(lái)說(shuō)G3比D8更小,總代價(jià)=已經(jīng)走過(guò)的距離 + 估值薇搁,估值可采用曼哈頓距離或者高斯距離)斋扰,需要搜索右上,右啃洋,上三個(gè)方向传货。向上搜索到跳點(diǎn)G2。

其余點(diǎn)路徑在圖上標(biāo)注宏娄,就不再重復(fù)了问裕。

實(shí)作中的搜索流程

(1) 若current方向是直線
i. 如果current左后方不可走且左方可走,則沿current左前方和左方尋找跳點(diǎn)孵坚。
ii. 如果current當(dāng)前方向可走粮宛,則沿current方向?qū)ふ姨c(diǎn)。
iii. 如果current右后方不可走且右方可走卖宠,則沿current右前方和右方尋找跳點(diǎn)巍杈。
(2) 若current方向是斜線
i. 如果當(dāng)前方向的水平分量可走,則沿current方向的水平分量方向?qū)ふ姨c(diǎn)逗堵。
ii. 如果當(dāng)前方向可走秉氧,沿current方向?qū)ふ姨c(diǎn)眷昆。
iii. 如果當(dāng)前方向的垂直分量可走蜒秤,則沿current方向的垂直分量方向?qū)ふ姨c(diǎn)汁咏。

上述算法流程是建立在斜向不可穿過(guò)阻擋基礎(chǔ)上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末作媚,一起剝皮案震驚了整個(gè)濱河市攘滩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纸泡,老刑警劉巖漂问,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異女揭,居然都是意外死亡蚤假,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門吧兔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)磷仰,“玉大人,你說(shuō)我怎么就攤上這事境蔼≡钇剑” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵箍土,是天一觀的道長(zhǎng)逢享。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吴藻,這世上最難降的妖魔是什么瞒爬? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮沟堡,結(jié)果婚禮上疮鲫,老公的妹妹穿的比我還像新娘。我一直安慰自己弦叶,他們只是感情好俊犯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伤哺,像睡著了一般燕侠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上立莉,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天绢彤,我揣著相機(jī)與錄音,去河邊找鬼蜓耻。 笑死茫舶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刹淌。 我是一名探鬼主播饶氏,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼讥耗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了疹启?” 一聲冷哼從身側(cè)響起古程,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喊崖,沒想到半個(gè)月后挣磨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荤懂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年茁裙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片节仿。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呜达,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粟耻,到底是詐尸還是另有隱情查近,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布挤忙,位于F島的核電站霜威,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏册烈。R本人自食惡果不足惜戈泼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赏僧。 院中可真熱鬧大猛,春花似錦、人聲如沸淀零。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驾中。三九已至唉堪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肩民,已是汗流浹背唠亚。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留持痰,地道東北人灶搜。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親割卖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子前酿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • sì 支zhī茶chá 對(duì)duì 酒jiǔ,賦fù 對(duì)duì 詩(shī)shī究珊,燕yàn子zi 對(duì)duì 鶯yīng 兒é...
    每個(gè)人的孟母堂閱讀 1,210評(píng)論 0 6
  • 一年級(jí)語(yǔ)文上冊(cè)生字表 生字表一(共400字) 啊(ā)愛(ài)安(ān)岸(àn)爸(bà)八(bā)巴(bā)...
    meychang閱讀 2,796評(píng)論 0 6
  • 原文:http://www.cnblogs.com/wangnfhy/p/4956711.html 參考:http...
    top_liu閱讀 1,631評(píng)論 0 52
  • 圍棋是兵法,也是勢(shì)的哲學(xué)纵苛,得勢(shì)者得天下剿涮。勢(shì)者,因利而制權(quán)攻人。像水一樣取试,行乎當(dāng)行,止乎當(dāng)止怀吻,從不刻意而為瞬浓,無(wú)為而無(wú)不為...
    三清未央閱讀 453評(píng)論 0 0
  • JavaScript擁有動(dòng)態(tài)類型,這意味著相同的變量可用作不同的類型。 字符串 字符串是存儲(chǔ)字符的變量蓬坡,單引號(hào)雙引...
    一畝水塘閱讀 386評(píng)論 0 4