成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

對狄克斯特拉算法的理解

chuyao / 1212人閱讀

摘要:致敬首先向偉大的牛人致敬使用狄克斯特拉算法如果所示找出從起點到終點耗時最短的路徑。狄克斯特拉算法思路步驟或思路如下找出最便宜的節(jié)點,即可在最短時間內前往的節(jié)點。

狄克斯特拉算法是一種實現(xiàn)了在有障礙物的兩個地點之間找出一條最短路徑的高效算法,解決了機器人學中的一個十分關鍵的問題,即運動路徑規(guī)劃問題,至今仍被廣泛應用。是“貪心方法(greedy method)”的一個成功范例。
致敬

首先向偉大的牛人致敬!

使用狄克斯特拉算法

如果所示:

找出從起點到終點耗時最短的路徑。其中,每個數(shù)字表示的都是時間,單位分鐘。線路使用有方向的箭頭線路表示,表示只有一個方向可以使用,統(tǒng)稱有向圖。

常規(guī)思路

為了找到從起點到終點耗時最短的路徑,我們通常需要找出從起點到終點所有的路徑,然后進行一一對比。

路徑一

路徑一是從起點出發(fā),經過 A 節(jié)點,到達終點,共計用時 6 + 1 = 7 分鐘。

路徑二

路徑二是從起點出發(fā),經過 B 節(jié)點,到達終點,共計用時 2 + 5 = 7 分鐘。

路徑三

路徑三從起點出發(fā),經過 B 節(jié)點,再經過 A 節(jié)點,到達終點,共計用時 2 + 3 + 1 = 6 分鐘。

綜上,我們已經窮舉完了所有可能的路徑,不可能再找出另外的路徑了。同時,對比一下三種路徑,你會發(fā)現(xiàn)路徑三用時最短,只需要 6 分鐘。呵呵,so easy,媽媽再也不用擔心我的學習了。既然,人可以做出結果,那么計算機利用此種方法,也就是所謂的窮舉法,當然也能找到最優(yōu)路徑。

不過,別得意,你的媽媽還得擔心你的學習。如果路途中,不止 A、B 兩個節(jié)點,而是接近無窮多個節(jié)點,記住是接近無窮多個節(jié)點,......懵逼從天空飄過。

此時,肯定有同學會跳出來反對,無窮多個節(jié)點,這就是無限。無限,也就是無界,就是死循環(huán)的問題了,肯定無法得到答案,此題出得有問題。

這個問題提得好,必須有界才能有答案,該問題是接近無限多,也就是個很大很大的邊界,是超出了人力范圍的邊界。......懵逼繼續(xù)從天空飄過。 但是,計算機肯定是能夠計算出有界的問題的,利用窮舉法當然可以算出,不過這里又產生一個問題,窮舉法是檢索每條可能的路徑,這肯定會消耗很大的計算機運算能力,那么有沒有更優(yōu)的方法,至少不用窮舉出所有路徑的方法呢?當然,有那么多的牛人供我們致敬,答案是肯定的。

狄克斯特拉算法思路

步驟或思路如下:

找出最便宜的節(jié)點,即可在最短時間內前往的節(jié)點。

對于該節(jié)點的所有鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷。

處理過的節(jié)點,進行標記,以后將不再處理。

重復以上過程,直到對圖中的每個節(jié)點都這樣做了。

計算出最終路徑。

第一步:找出最便宜的節(jié)點。你站在起點,不知道該前往節(jié)點 A 還是節(jié)點 B ,茫然無措ing........。此時,散列表可以派上用場了。啥是散列表?你可以把它當做是一個列表,詳細的東西問谷歌,請自備梯子

前往節(jié)點 A 需要6 分鐘,而前往節(jié)點 B 需要 2 分鐘。至于前往其它節(jié)點,你還不知道需要多長時間。那么散列表如下:

父節(jié)點 節(jié)點 耗時
起點 A 6
起點 B 2
起點 終點

第二步:由于從起到到節(jié)點 B 的路徑耗時少,先計算經節(jié)點 B 前往其各個鄰居所需的時間。

父節(jié)點 節(jié)點 耗時
B A 5 更新耗時
- B 2
B 終點 7 更新耗時

這一步,找到了一條前往節(jié)點 A 的更短路徑!直接前往節(jié)點 A 需要 6 分鐘。但是經過節(jié)點 B 前往節(jié)點 A 只需要 5 分鐘。

對于節(jié)點 B 的鄰居,如果找到前往它的更短路徑,就更新其開銷。

前往節(jié)點 A 的更短路徑,時間從 6 分鐘縮短到 5 分鐘。

前往終點的更短路徑,時間從無窮大縮短到 7 分鐘。

第三步:對節(jié)點 B 已進行處理,所以要對節(jié)點 B 進行標記,以后將不再處理節(jié)點 B。

第四部: 重復!

重復第一步:找出可在最短時間內前往的節(jié)點。除節(jié)點 B 之外,可以在最短時間內前往的節(jié)點是節(jié)點 A 。
重復第二步:更新節(jié)點 A 的所有鄰居的開銷。

父節(jié)點 節(jié)點 耗時
- A 5 已是最小耗時,無需更新
- B 2
A 終點 6 更新耗時

現(xiàn)在對每個節(jié)點都運行了狄克斯特拉算法(無需對終點這樣做)?,F(xiàn)在,你知道:

前往節(jié)點 B 需要 2 分鐘;

前往節(jié)點A 需要 5 分鐘;

前往終點需要 6 分鐘。

所以你會發(fā)現(xiàn),前往終點的時間為 6 分鐘!?。?/strong>

Python代碼實現(xiàn) 實現(xiàn)一個能夠找出開銷最低節(jié)點的函數(shù)
def find_lowest_cost_node(costs):
    lowest_cost = float("inf") # 設置初始開銷為無窮大,因為你現(xiàn)在很茫然
    lowest_cost_node = None # 設置初始最低開銷節(jié)點為 None
    for node in costs: # 遍歷所有的節(jié)點
        cost = costs[node]
        if cost < lowest_cost and node not in processed: # 如果當前節(jié)點的開銷更低且未處理過,
            lowest_cost = cost # 就將其視為開銷最低的節(jié)點。
            lowest_cost_node = node # 最低開銷節(jié)點為當前的節(jié)點。
    return lowest_cost_node
創(chuàng)建用于存儲所有節(jié)點及其前往鄰居開銷的散列表代碼
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] =1

graph["b"] = {}
graph["b"]["a"] =3
graph["b"]["fin"] = 5

graph["fin"] = {} # 終點沒有任何鄰居

表示整個圖的散列表類似下面這樣。

父節(jié)點 節(jié)點 耗時
起點 A 6
起點 B 2
A 終點 1
B A 3
B 終點 5
起點 終點 -
按流程實現(xiàn)代碼

一、創(chuàng)建從起點開始的開銷表代碼如下:

infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity

二、創(chuàng)建存儲父節(jié)點的散列表代碼如下:

parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

三、創(chuàng)建一個數(shù)組,用于記錄處理過的節(jié)點,對于同一個節(jié)點,不用多次處理。

processed = []

四、按照算法列出代碼

node = find_lowest_cost_node(costs) # 在未處理的節(jié)點中找出開銷最小的節(jié)點
while node is None: # 這個 while 循環(huán)在所有節(jié)點都被處理過后結束
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys(): # 遍歷當前節(jié)點的所有鄰居
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost: # 如果經當前節(jié)點前往該鄰居最近,
            costs[n] = new_cost # 就更新該鄰居的開銷
            parents[n] = node # 同時將該鄰居的父節(jié)點設置為當前節(jié)點
    processed.append(node) # 將當前借調標記為已處理
    node = find_lowest_cost_node(costs) # 找出接下來要處理的節(jié)點,并循環(huán)。
按照個人的理解創(chuàng)建代碼

在 Python 3.5.2 上親測有效。

# -*- coding:utf-8 -*-
__author__ = "東方鶚"
__blog__ = "www.os373.cn"

def find_lowest_cost_node(costs, processed):
    lowest_cost = float("inf") # 設置初始開銷為無窮大,因為你現(xiàn)在很茫然
    lowest_cost_node = None # 設置初始最低開銷節(jié)點為 None
    for node in costs: # 遍歷所有的節(jié)點
        cost = costs[node]
        if cost < lowest_cost and node not in processed: # 如果當前節(jié)點的開銷更低且未處理過,
            lowest_cost = cost # 就將其視為開銷最低的節(jié)點。
            lowest_cost_node = node # 最低開銷節(jié)點為當前的節(jié)點。
    return lowest_cost_node


def best_route():
    """ 存儲所有節(jié)點及其下一個節(jié)點開銷的字典 """
    graph = {"start": {"a": 6, "b": 2}, "a": {"fin": 1}, "b": {"a": 3, "fin": 5}, "fin": {}}

    """ 從起點開始,包含所有下一個節(jié)點開銷的字典 """
    infinity = float("inf")
    costs = {"a": 6, "b": 2, "fin": infinity}

    """ 從起點開始,存儲所有父節(jié)點的散列表 """

    parents = {"a": "start", "b": "start", "fin": None}
    best_route = ""
    processed = []

    node = find_lowest_cost_node(costs, processed) # 在未處理的節(jié)點中找出開銷最小的節(jié)點    
    while node is not None: # 這個 while 循環(huán)在所有節(jié)點都被處理過后結束
        cost = costs[node]
        neighbors = graph[node]
        for n in neighbors.keys(): # 遍歷當前節(jié)點的所有鄰居
            new_cost = cost + neighbors[n]
            if costs[n] > new_cost: # 如果經當前節(jié)點前往該鄰居最近,
                costs[n] = new_cost # 就更新該鄰居的開銷
                parents[n] = node # 同時將該鄰居的父節(jié)點設置為當前節(jié)點
        processed.append(node) # 將當前借調標記為已處理
        node = find_lowest_cost_node(costs, processed) # 找出接下來要處理的節(jié)點,并循環(huán)。
    
    p = parents["fin"]
    
    while True:  
        best_route += "%s<——" % p
        p = parents[p]
        
        if p is "start":
            break               
        
                
    return "到達終點的最終路徑是: 終點<——%s起點。
最快到達的時間是%s分鐘" % (best_route, costs["fin"])
        
if __name__ == "__main__":
    best_route = best_route()
    print(best_route)

結果如下:

到達終點的最終路徑是: 終點<——a<——b<——起點。
最快到達的時間是6分鐘
狄克斯特拉算法的局限

1、該算法只適用于有向無環(huán)圖!
2、該算法將 0 視作最小的權值,也就是說,如果出現(xiàn)負權值的情況,那么該算法將失效!

reference

《算法圖解》

本人用C作的視頻,敬請點閱

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/40911.html

相關文章

  • 【你該懂一點Javascript算法系列】之單源最短路徑 - Dijkstra算法

    摘要:算法系列單源最短路徑算法迪杰斯特拉算法是由荷蘭計算機科學家狄克斯特拉于年提出的,因此又叫狄克斯特拉算法。是從一個頂點到其余各頂點的最短路徑算法,解決的是有向圖中最短路徑問題。 Javascript算法系列 - 單源最短路徑 - Dijkstra算法 迪杰斯特拉算法是由荷蘭計算機科學家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個頂點到其余各頂點的最短路徑算法,解決的是有...

    SoapEye 評論0 收藏0
  • 算法系列——JavaScript中廣度優(yōu)先搜索思想實現(xiàn)

    摘要:散列表上面的地圖向我們展示了如何用廣度優(yōu)先搜索的思想找到北京到廣州的最短路線。在廣度優(yōu)先搜索中,我們需要用到隊列的這種思想來實現(xiàn)查找。建立了下面這個模型武漢廣州西藏上海上海武漢廣州代碼完整實現(xiàn),利用遞歸和廣度優(yōu)先搜索的思想實現(xiàn)。 什么是廣度優(yōu)先搜索? 如果只是是背概念,幼兒園的小朋友都能背下來念給你聽。 假設看這篇文章的都和我一樣是個前端工程師,我們要從廣度優(yōu)先搜索(BFS)中學到什么...

    everfly 評論0 收藏0
  • 尋路之 A* 搜尋算法

    摘要:但再認真想想,其實這道題目就類似我們日常用的導航,尋找起點和終點可行的最短路線。越小時,那么起點到目標點的可行路徑越小。首先將起點放進中,然后搜尋起點附近可行方格放到中作記錄。 showImg(https://segmentfault.com/img/remote/1460000009932413?w=660&h=440); 最近做到一道題,題目如下: 有 A、B 兩點,中間有一堆障礙...

    banana_pi 評論0 收藏0
  • 漫談 | “黎曼猜想”和區(qū)塊鏈加密算法到底有什么關系?

    摘要:假如黎曼猜想被證實,區(qū)塊鏈將毀滅近日,黎曼猜想四個字瘋狂刷屏。黎曼猜想由數(shù)學家波恩哈德黎曼于年提出。因此,黎曼猜想一旦被證明,則意味著素數(shù)之密被解開,算法也就將被攻破了。而大多數(shù)區(qū)塊鏈所用的加密算法不是,而是橢圓曲線加密算法。 瑪麗女王的密碼之生死命懸一線 showImg(https://segmentfault.com/img/bVbhD7s?w=740&h=876); 16世紀伊麗...

    tracymac7 評論0 收藏0

發(fā)表評論

0條評論

chuyao

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<