最短路徑算法

算法思想?

?從起始點(diǎn)開始葛超,采用貪心算法的策略,每次遍歷到始點(diǎn)距離最近且未訪問過的頂點(diǎn)的鄰接節(jié)點(diǎn),直到擴(kuò)展到終點(diǎn)為止津畸。 每次選擇距離起始點(diǎn)最近的節(jié)點(diǎn), 然后以此不斷向外擴(kuò)展, 直至達(dá)到終點(diǎn)

?算法描述(步驟)?

1: 定義集合, S = {u}, Q= v - S, 定義dist: 起始點(diǎn)距離其他節(jié)點(diǎn)的距離?

2: 在Q中找出距離起點(diǎn)最近的節(jié)點(diǎn)加入 S中, 然后更新dist

?3: 重復(fù)2, 直接Q集合為空, dist就是所求的內(nèi)容 比較難理解的算法需要演練下?

算法偽代碼實(shí)現(xiàn)

?1: 定義visit數(shù)組: 為1代表已經(jīng)被訪問過?

find u-> minQ(u) && visit[u] == 0?

update dist[i]: if dist[i] > dist[u]+cost[i][u]?

2: 使用最小堆做優(yōu)化?

get minQ(u) in minheap?

update dist[i]: if dist[i] > dist[u]+cost[i][u]

?有興趣寫下具體實(shí)現(xiàn)

```

type?nodeinfo?struct?{

????targetNode?int

????distance?int

????index?int

}

type?nodeinfos?[]*nodeinfo

const?Inf?=?1e9

func?(nodes?*nodeinfos)?Len()?int?{

????return?len(*nodes)

}

func?(nodes?*nodeinfos)?Less(i,?j?int)?bool?{

????return?(*nodes)[i].distance?<?(*nodes)[j].distance

}

func?(nodes?*nodeinfos)?Swap(i,?j?int)?{

????(*nodes)[i],?(*nodes)[j]?=?(*nodes)[j],?(*nodes)[i]

????(*nodes)[i].index?=?i

????(*nodes)[j].index?=?j

}

func?(nodes?*nodeinfos)?Push(x?interface{})?{

????n?:=?len(*nodes)

????item?:=?x.(*nodeinfo)

????item.index?=?n

????*nodes?=?append(*nodes,?item)

}

func?(nodes?*nodeinfos)?Pop()?interface{}?{

????if?len((*nodes))?<=?0?{

????????return?nil

????}

????x?:=?(*nodes)[len((*nodes))-1]

????(*nodes)?=?(*nodes)[:len((*nodes))-1]

????return?x

}

//n個(gè)節(jié)點(diǎn),?k為起始節(jié)點(diǎn)必怜,?cost為鄰接矩陣

func?Dijkstra(cost?[][]int,?N?int,?start?int,?end?int)?(res?[][]int)?{

????dist?:=?make([]int,?N)

????for?i?:=?0;?i?<?N;?i++?{

????????dist[i]?=?Inf

????}

????dist[start]?=?0

????nodemap?:=?map[int]*nodeinfo{}

????heapElement?:=?make(nodeinfos,?0)

????heap.Init(&heapElement)

????nodeptr?:=?&nodeinfo{

????????targetNode:?start,

????????distance:?0,

????}

????heap.Push(&heapElement,?nodeptr)

????nodemap[start]?=?nodeptr

????relayNodes?:=?make([][]int,?N)//源節(jié)點(diǎn)到各節(jié)點(diǎn)的最后一個(gè)中轉(zhuǎn)節(jié)點(diǎn)

????for?i?:=?0;?i?<?N;?i++?{

????????relayNodes[i]?=?make([]int,?0)

????}

????relayNodes[start]?=?append(relayNodes[start],?start)

????for?len(heapElement)?>?0?{

????????minNode?:=?heap.Pop(&heapElement).(*nodeinfo)

????????delete(nodemap,?minNode.targetNode)

????????if?minNode.targetNode?==?end?{

????????????res?=?getAllTreePaths(relayNodes,?start,?end)

????????????return

????????}

????????for?i?:=?0;?i?<?N;?i++?{

????????????if?cost[minNode.targetNode][i]?==?Inf?{

????????????????continue

????????????}

????????????distance?:=?dist[minNode.targetNode]?+?cost[minNode.targetNode][i]

????????????if?distance?<?dist[i]?{

????????????????relayNodes[i]?=?make([]int,?0)

????????????}

????????????if?distance?<=?dist[i]?&&?i?!=?minNode.targetNode?{

????????????????relayNodes[i]?=?append(relayNodes[i],?minNode.targetNode)

????????????}

????????????if?distance?<?dist[i]?{

????????????????dist[i]?=?distance

????????????????if?value,?ok?:=?nodemap[i];?ok?{

????????????????????value.distance?=?distance

????????????????????heap.Fix(&heapElement,?value.index)

????????????????}?else?{

????????????????????heap.Push(&heapElement,?&nodeinfo{

????????????????????????targetNode:?i,

????????????????????????distance:?distance,

????????????????????})

????????????????}

????????????}

????????}

????}

????return

}

func?getAllTreePaths(relayNodes?[][]int,?start?int,?end?int)?[][]int?{

????path?:=?make([]int,?0)

????allpath?:=?[][]int{}

????getAllResults(relayNodes,?start,?end,?path,?&allpath)

????length?:=?len(allpath)?-?1

????for?i?:=?0;?i?<=?length;?i++?{

????????length2?:=?len(allpath[i])

????????for?j?:=?0;?j?<?length2?/?2;?j++?{

????????????allpath[i][j],?allpath[i][length2-j-1]?=?allpath[i][length2-j-1],?allpath[i][j]

????????}

????}

????return?allpath

}

func?getAllResults(relayNodes?[][]int,?start?int,?end?int,?path?[]int,?allpath?*[][]int)??{

????if?(start?==?end?||?len(relayNodes[end])?==?0)?{

????????path?=?append(path,?end)

????????*allpath?=?append(*allpath,?path)

????????return

????}

????path?=?append(path,?end)

????nodes?:=?relayNodes[end]

????for?i?:=?0;?i?<?len(nodes);?i++?{

????????getAllResults(relayNodes,?start,?nodes[i],?path,?allpath)

????}

}


注意: 有關(guān)堆的使用可以看:? go自帶的test用例, 寫的比較好, 特別是fix使用方法值得學(xué)習(xí)

```

應(yīng)用場景?

? 1: 從地點(diǎn)a達(dá)到地點(diǎn)b, 如何走最短?

? 2: 有關(guān)求最短路徑或者最短步驟的, 都可以試著把問題抽象成圖, 然后解之

擴(kuò)展算法

? ? Floyd算法等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肉拓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子梳庆,更是在濱河造成了極大的恐慌暖途,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膏执,死亡現(xiàn)場離奇詭異驻售,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)更米,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門芋浮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事纸巷≌虿荩” “怎么了?”我有些...
    開封第一講書人閱讀 157,812評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵瘤旨,是天一觀的道長梯啤。 經(jīng)常有香客問我,道長存哲,這世上最難降的妖魔是什么因宇? 我笑而不...
    開封第一講書人閱讀 56,607評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮祟偷,結(jié)果婚禮上察滑,老公的妹妹穿的比我還像新娘。我一直安慰自己修肠,他們只是感情好贺辰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嵌施,像睡著了一般饲化。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吗伤,一...
    開封第一講書人閱讀 49,919評(píng)論 1 290
  • 那天吃靠,我揣著相機(jī)與錄音,去河邊找鬼足淆。 笑死巢块,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的巧号。 我是一名探鬼主播族奢,決...
    沈念sama閱讀 39,071評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼裂逐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泣栈,我...
    開封第一講書人閱讀 37,802評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤卜高,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后南片,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掺涛,經(jīng)...
    沈念sama閱讀 44,256評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評(píng)論 2 327
  • 正文 我和宋清朗相戀三年疼进,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薪缆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,712評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伞广,死狀恐怖拣帽,靈堂內(nèi)的尸體忽然破棺而出疼电,到底是詐尸還是另有隱情,我是刑警寧澤减拭,帶...
    沈念sama閱讀 34,389評(píng)論 4 332
  • 正文 年R本政府宣布蔽豺,位于F島的核電站,受9級(jí)特大地震影響拧粪,放射性物質(zhì)發(fā)生泄漏修陡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評(píng)論 3 316
  • 文/蒙蒙 一可霎、第九天 我趴在偏房一處隱蔽的房頂上張望魄鸦。 院中可真熱鬧,春花似錦癣朗、人聲如沸拾因。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盾致。三九已至,卻和暖如春荣暮,著一層夾襖步出監(jiān)牢的瞬間庭惜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評(píng)論 1 266
  • 我被黑心中介騙來泰國打工穗酥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留护赊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,473評(píng)論 2 360
  • 正文 我出身青樓砾跃,卻偏偏與公主長得像骏啰,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抽高,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評(píng)論 2 350