spfa算法


spfa的算法思想(動態逼近法):
    設立一個先進先出的隊列q用來保存待優化的結點,優化時每次取出隊首結點u,並且用u點當前的最短路徑估計值對離開u點所指向的結點v進行松弛操作,如果v點的最短路徑估計值有所調整,且v點不在當前的隊列中,就將v點放入隊尾。這樣不斷從隊列中取出結點來進行松弛操作,直至隊列空為止。 
    松弛操作的原理是著名的定理:“三角形兩邊之和大於第三邊”,在信息學中我們叫它三角不等式。所謂對結點i,j進行松弛,就是判定是否dis[j]>dis[i]+w[i,j],如果該式成立則將dis[j]減小到dis[i]+w[i,j],否則不動。 
    下面舉一個實例來說明SFFA算法是怎樣進行的:




和廣搜bfs的區別:
    SPFA 在形式上和廣度(寬度)優先搜索非常類似,不同的是bfs中一個點出了隊列就不可能重新進入隊列,但是SPFA中一個點可能在出隊列之后再次被放入隊列,也就是一個點改進過其它的點之后,過了一段時間可能本身被改進(重新入隊),於是再次用來改進其它的點,這樣反復迭代下去。

算法的描述:

void  spfa(s);  //求單源點s到其它各頂點的最短距離
    for i=1 to n do { dis[i]=∞; vis[i]=false; }   //初始化每點到s的距離,不在隊列
    dis[s]=0;  //將dis[源點]設為0
    vis[s]=true; //源點s入隊列
    head=0; tail=1; q[tail]=s; //源點s入隊, 頭尾指針賦初值
    while head<tail do {
       head+1;  //隊首出隊
       v=q[head];  //隊首結點v
       vis[v]=false;  //釋放對v的標記,可以重新入隊
       for 每條邊(v,i)  //對於與隊首v相連的每一條邊
        if (dis[i]>dis[v]+a[v][i])  //如果不滿足三角形性質
         dis[i] = dis[v] + a[v][i]   //松弛dis[i]
        if (vis[i]=false) {tail+1; q[tail]=i; vis[i]=true;} //不在隊列,則加入隊列
    } 

 


免責聲明!

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



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