最佳路徑搜索算法1


算法,就是(結合各種數學知識)解決問題的有限步驟,可以表現為程序、流程圖。

 

假設要尋找一條路徑,從起點S,終點G。

有幾個關鍵原則:

1. 路徑的下一個節點,不能和以往節點相同,否則會造成死循環。

2. 所有“待選”,“待算”路徑,放在一個列表中;

OK,現在可以假設,有基礎數據,各個點的坐標:

struct Point {

  char ID;

  double x;

  double y;

}

各個可走路徑的長度

struct distance

{

  char Id1;

  char id2;

  double lenght;

}

那么,我們想要的結果,是:

struct Path {

  List<int> Ids; //一個有序的節點集合


 

british museum算法

這個算法,說白了就是構造一顆樹,沒什么目的的構造,造到死胡同為止,最后看看那條包含S和G

要實現這個算法,需要兩個列表,一個存放所有走到死胡同的路徑R,一個存放還沒走到死胡同的路徑T。

被划去的路徑,例如:在上一步演變到下一步中划去的。

算法開始:

1.  T:(S)   R:空

2.  T:(S,A),(S,B)  R:空

3.  T:(S,A,B),(S,A,D),(S,B)  R:空

4.  T:(S,A,B,C),(S,A,D),(S,B)  R:空

5.  T:(S,A,B,C,E)(S,A,D),(S,B)  R:空

6.  T:(S,A,D,G)(S,B)  R:(S,A,B,C,E)

7.  T:(S,B,A),(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

8.  T:(S,B,A,D),(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

9.  T:(S,B,A,D,G)(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

10.  T:(S,B,C,E)  R:(S,A,B,C,E),(S,A,D,G),(S,B,A,D,G)

11.  T:空  R:(S,A,B,C,E),(S,A,D,G),(S,B,A,D,G),(S,B,C,E)

12. 看看R中那條路徑含有S和G,S到G的距離那條最短即可。

偽代碼:

while(T.Count > 0)

{

  if ( T[0]的最后一個節點不是G && 能T[0]的下一個節點 的數目n > 0  )

    復制n個T[0],然后分別往后邊添加可添加的節點; 

    移除T的第0個元素;

    將新的n個隊列插入到T的前面;

  else

    將T的第0個元素放進R;

    移除T的第0個元素;

}


 

deepth first(深度優先)算法

和british museum算法不同的地方是:1. 不需要結果列表;2. 發現目標馬上停下來;3. 有回溯

缺點:不能總是發現最優路徑

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,A,B),(S,A,D),(S,B)   

4.  T:(S,A,B,C),(S,A,D),(S,B)   

5.  T:(S,A,B,C,E)(S,A,D),(S,B)   

6.  T:(S,A,D,G),(S,B) 

偽代碼:

while(T.Count>0)

{

    if ( 能T[0]的下一個節點 的數目n > 0  )

        if (能加在T[0]后的節點有G)

          返回T[0] + G的路徑

        else

          復制n個T[0],然后分別往后邊添加可添加的節點;

          移除T的第0個元素

          將新的n個隊列插入到T的前面(這個是算法最要特點)

    else

      移除T的第0個元素

}

 


 breadth first(廣度優先)算法

和british museum算法不同的地方是:1. 實現上將擴展后的路徑,放到列表后邊;2. 沒回溯

比深度優先的優點是,更早發現路徑的路線,雖然本例子是同一個,但難保“右”邊出現G比較快。

缺點:較“淺”的不一定是路徑最短的。

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,B),(S,A,B),(S,A,D)   

4.  T:(S,A,B),(S,A,D),(S,B,A), (S,B,C)

5.  T:(S,A,D),(S,B,A), (S,B,C),(S,A,B,C)

6.  T:(S,B,A), (S,B,C),(S,A,B,C),(S,A,D,G)

 


breadth first(廣度優先)算法的優化

以上,無論哪個算法,都會對同一節點考慮多次,例如:

那么,優化的地方是,考慮過的節點不再考慮,變為:

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,B),(S,A,D)   

4.  T:(S,A,D), (S,B,C)

5.  T:(S,B,C),(S,A,D,G) 

在實現上,對比廣度算法,只需要在添加到列表后邊前,去除部分不再考慮的節點。


hill climing算法:在深度優先的基礎上改進

有不斷擴展節點,回溯,使用啟發信息的特點

特點:在深度優先的基礎上,只考慮離目標直線距離最近的節點。

區別: 在將新的路線插入隊列前,先根據離目標的距離,按升序排列。

缺點:這種是一種比較“短視”的算法。

優點:如果路網太復雜的話,效果可能更好

 

 

1.  T:(S)   

2.  T:(S,B),(S,A)          (這里發生了排序)

3.  T:(S,B,C),(S,B,A),(S,A)  (這里發生了排序)

4.  T:(S,B,C,E)(S,B,A),(S,A)   

5.  T:(S,B,A,D),(S,A)  

6.  T:(S,B,A,D,G),(S,A) 

 


 

束搜索:廣度優先的改良,使用“知情啟發信息”

區別:1. 在廣度優先中,限制每一層中考慮的路徑數量w;2.  節點重復的不考慮;3. 將距離教小的值放到隊列前面

關鍵:設置好w值

 

1.  T:(S)   

2.  T:(S,B) ,(S,A)  //B點比A點近

3.  T:(S,A),(S,B,C)   

4.  T:(S,B,C),(S,A,D)

5.  T:(S,A,D)(S,B,C,E)

6.  T:(S,A,D,G) 

 

偽代碼:

while(T.Count>0)

{

    if ( 能T[0]的下一個節點 的數目n > 0  )

        if (能加在T[0]后的節點有G)

          返回T[0] + G的路徑;

        else

          移除n個節點中,在路徑已經出現過節點          

          復制 ≤ n個T[0],然后分別往后邊添加可添加的節點;

          移除T的第0個元素;

          對 ≤ n個T[0]延伸路徑,根據最后一個節點對G點的距離,按升序排列,並取前w個T[0]的延伸路徑;(這個是算法主要特點)

          將新w個T[0]的延伸路徑插入到T的后面(這個是算法主要特點)

    else

      移除T的第0個元素

}


搜索辦法 回溯          節點擴展    使用啟發式信息 擴展路徑插入方式
british museum false false false  
深度優先(deepth first) true true false
廣度優先(breath first) false true false
爬山算法(hill climing) true true true
束搜素 false false true

 

*節點擴展,在實現上,將新的擴展路徑加入到隊列的前面;思想上,是否對新的擴展路徑“一路走到黑”

*回溯,在實現上,將新的擴展路徑加入到隊列的前面;新的路徑走到死胡同后,及時丟棄;

*啟發式信息,是否使用坐標值來優化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM