廣度優先和深度優先和貪心法和Dijkstra和A*演算法的總結
廣度優先總結
1.在各個方向上都有同樣的探索。
對於一個圖他的廣度優先遍歷的步驟:
1.利用佇列實現
2.從源節點開始依次按照寬度進佇列,然後彈出
3.每彈出一個節點,就把該節點所有沒有進過佇列的鄰接點放入佇列
4.直到佇列變空
frontier = Queue() frontier.put(start ) came_from = {} came_from[start] = None while not frontier.empty(): current = frontier.get() if current == goal: break for next in graph.neighbors(current): if next not in came_from: frontier.put(next) came_from[next] = current
深度優先總結
1.在各個方向上都有同樣權重的探索。遍歷的順序不一樣
針對一個圖的他深度優先遍歷的步驟:
1.利用棧實現
2.從源節點開始把節點按照深度放入棧,然後彈出
3.每彈出一個點,把該節點下一個沒有進過棧的鄰接點放入棧
4.直到棧變空
Dijkstra總結:
1.考慮到成本,對於路徑搜尋,走不同的路徑他花的成本是不一樣的。
2.我們新增一個新的變數跟蹤從開始位置的總移動成本。我們想在決定如何評估地點時考慮到移動成本;讓我們將佇列轉換為優先佇列。我們可能會多次訪問一個位置,如果成本變小了就更新字典邏輯。
3.從起始點開始在森林中緩慢地擴張
frontier = PriorityQueue() frontier.put(start, 0) came_from = {} cost_so_far = {} came_from[start] = None cost_so_far[start] = 0 while not frontier.empty(): current = frontier.get() if current == goal: break for next in graph.neighbors(current): new_cost = cost_so_far[current] + graph.cost(current, next) if next not in cost_so_far or new_cost < cost_so_far[next]: cost_so_far[next] = new_cost priority = new_cost frontier.put(next, priority) came_from[next] = current
貪心法總結:
貪心演算法是指在對問題求解時,比如路徑尋找,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的區域性最優解。是一種啟發式的方法
frontier = PriorityQueue() frontier.put(start, 0) came_from = {} came_from[start] = None while not frontier.empty(): current = frontier.get() if current == goal: break for next in graph.neighbors(current): if next not in came_from: priority = heuristic(goal, next) frontier.put(next, priority) came_from[next] = current
A*總結:
Dijkstra和貪心演算法的缺點:
1.Dijkstra演算法很好地找到了最短路徑,但它浪費了時間去探索那些沒有前途的方向。
2.貪婪的最好的第一次搜尋在有希望的方向上探索,但它可能找不到最短的路徑。
A*的做法:
A*演算法結合了這兩種方法,演算法使用從開始的實際距離和估計的距離到目標的距離。
演算法:Dijkstra演算法計算出起點的距離。貪婪的第一次搜尋估計到目標點的距離。A是用這兩個距離的和。
在不同的地方開了一個洞。你會發現,當貪婪的最好的第一次搜尋找到正確答案時,你也會發現它,探索同一領域。當貪婪的第一次搜尋找到了錯誤的答案(較長的路徑)時,找到了正確的答案,就像Dijkstra演算法所做的那樣,但仍然比Dijkstra演算法所做的要少。
A演算法只要啟發式距離不高於實際距離,就會找到一條最優路徑,就像Dijkstra演算法所做的那樣。A使用啟發式方法對節點重新排序,以便更有可能更快地遇到目標節點。
frontier = PriorityQueue() frontier.put(start, 0) came_from = {} cost_so_far = {} came_from[start] = None cost_so_far[start] = 0 while not frontier.empty(): current = frontier.get() if current == goal: break for next in graph.neighbors(current): new_cost = cost_so_far[current] + graph.cost(current, next) if next not in cost_so_far or new_cost < cost_so_far[next]: cost_so_far[next] = new_cost priority = new_cost + heuristic(goal, next) frontier.put(next, priority) came_from[next] = current
區別:
1.如果您想要找到所有位置的路徑,請使用廣度優先搜尋或Dijkstra演算法。如果移動成本都是一樣的,使用廣度優先搜尋;如果移動成本不同,使用Dijkstra演算法。
2.如果你想找到一個位置的路徑,使用貪婪最好的第一次搜尋或A。在大多數情況下使用A。當你想要使用貪婪最好的第一次搜尋時,考慮使用一個“不可接受”的啟發式。
3 那麼最佳路徑呢?廣度優先搜尋和Dijkstra演算法保證在輸入圖中找到最短路徑。貪婪最好的第一次搜尋不是。如果啟發式永遠不會大於實際距離,則保證找到最短路徑。當啟發式變得更小時,就變成了Dijkstra演算法。當啟發式變得更大時,就變成了貪婪的第一次搜尋。
3D-A*演算法的改進:
1.更改輸入為3維的輸入,以及包含權重和障礙點。
2.更改節點的鄰居包含時間維度,即(-1,0,1)(1,0,1)(0,-1,1)(0,1,1),(0,0,1)
計算量大的改進:
3.因為時間的特殊性就是,過去了,不能回來了,根據這個特性,當沒有可走的路徑時,普通的A*是需要訪問到所有節點的,將一些不可能到達終點的一些點設為障礙點。節省了大量時間1/3的時間。