關於狄克斯特拉算法(dijkstra)總結


關於狄克斯特拉算法(dijkstra)總結
1,2,4是四個定點其他的是距離,從2到4最直接的就是2-4,但是不是最近的,需要舒展一下2-1-4,這樣只有8.所以才是最短的。這個過程就是狄克斯特拉算法。下面進入正題:
 
關於狄克斯特拉算法(dijkstra)總結

我們這里定義圖的編號為:

1 2 3

4 5 6

7 8 9

圖1:初始化的圖,其中包含邊的權值(耗時)。(這里圖是有向圖)。

圖2:確定起點,然后向能直接走到的點走一下,記錄此時的估計值:2 6 9.。

圖3:找到距離起點最近的點,是正東邊的那個點,這時候我們耗費權值為2。然后我們進行松弛操作,從起點到其東南方的點直接到的權值耗費為6,但是我們通過剛剛選定的點,我們找到了到這個點更近的方式,所以這個時候我們說從起點到其東南方向的點的權值更新值從6變成了5。這個時候我們就完成了第一次松弛操作。

圖4:依舊是找距離起點最近的點。然后松弛我們發現這個時候從起點到其東南方的點的耗費權值從5又變成了4.這個時候我們完成了第二個松弛。

之后的方式同上:選定距離起點最近的點v。然后通過點v進行松弛操作。我們發現能夠通過增加走到目的地方式的復雜度(多轉彎)的方式我們能夠松弛掉權值,使得耗費的權值更小。
     模板:

void Dij()//我們這里起點為1號編碼點。我們這里的d[]表示從起點到這個點需要的權值。w[a][b]表示點a到點b這條邊的權值.
{
 int i,j,k,v,tmp;
 memset(vis,0,sizeof(vis));
 for(i=1;i<=n;i++)
     d[i]=w[1][i];//對應圖不難理解,對於起點的初始化
 d[1]=0;
 vis[1]=1;
 for(i=1;i<=n;i++)//控制連接點的次數,例如上圖,九個點,就循環九次。
 {
  tmp=N;//這里N表示無窮大。也就是圖上的99.
  for(j=1;j<=n;j++)
  {
   if(tmp>d[j]&&!vis[j])
   {
    tmp=d[j];
    v=j;
   }
  }//每次我們都找到距離起點最近的點v
  vis[v]=1;
  for(k=1;k<=n;k++)//然后進行松弛操作。

我們這里的d[]表示從起點到這個點需要的權值//加以強調其含義。
{
    if(!vis[k])
   d[k]=min(d[k],d[v]+w[v][k]);
}
}
}
參考博客:http://blog.csdn.net/mengxiang000000/article/details/50421243
 

 


免責聲明!

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



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