最短路徑的最優子結構
最短路徑的子路徑也是最短路徑。
負權重的邊
權重為負數的邊。(我的理解:大概知道這個就可以了)
環路
最短路徑既不能包含正的環路,也不能包含負的環路。(正的環路,我覺得正常人想走最短的路,都不會在那裡打圈,除非路就是圓的;負環路你多繞幾圈,最後權重想變多小變多小,就很沒意思。)
最短路徑的表示
每個節點保持乙個前驅屬性v.π,指向它的前乙個結點。(這樣可以串成一串)
鬆弛操作
說白了就是就是檢查一下繞小路會不會更近。
v.d:表示s到v的最短路徑估計
接下來書中還有一堆性質,我就放圖,我自己也沒看,感覺很每意思,就是感覺把一些簡單的東西說的很複雜,顯得十分高大上。
我的思路:
這邊為什麼要先對點迴圈,然後再套乙個對邊的迴圈鬆弛呢?因為第一次鬆弛的時候,部分地方還不是最短路徑。這邊思路真的不是很好描述:最好的辦法就是自己按照它的流程走一遍!
1、對有向無環圖進行拓撲排序
2、再進行bellman類似操作
這一章我模稜兩可地看了看,emmm不知道它到底要講些什麼,如果你知道的話,請告訴我,謝謝!那麼我就要跳過這部分了。
dijkstra演算法解決的是帶權重的有向圖上單源最短路徑問題,要求所有邊權重大於0 。
我的感覺:它就是乙個改進的prim演算法。
我的思路:
1、每個點都有乙個mark屬性標誌著是否已經在路徑中
2、將邊從小排到大
3、如果點沒有全部加入到路徑中,從小到大遍歷每條邊,如果邊的起點在路徑中,邊的終點沒在路徑中,就把終點的前驅設定為起點,同時終點的mark屬性變為true
4、開始重新遍歷邊
24.5最短路徑性質的證明
四五兩章都非常的理論,我就不看了,真的很討厭這種看的頭疼又看不懂的東西。
以下就是**部分了(建議貼上到自己的編輯器中執行)
bellman.h
#pragma once
#define bellv 5/*點的數量*/
#define belle 10/*邊的數量*/
/*點*/
typedef struct bellv
bellv;
/*邊*/
typedef struct
belle;
/*圖*/
typedef struct
bellg;
/*初始化*/
void initbell(bellg* &g, bellv* root);
/*鬆弛操作*/
void bellrelax(bellv* u, bellv* v, int w);
/*bellman演算法*/
bool bellman(bellg* &g, bellv* root);
/*列印路徑*/
void bellprint(bellv *root, bellv *end);
/*測試函式*/
void testbellman();
bellman.cpp
#include "bellman.h"
#include#include#includeusing namespace std;
/*初始化*/
void initbell(bellg* &g,bellv* root)
root->d = 0;/*源結點*/
}/*鬆弛操作*/
void bellrelax(bellv* u, bellv* v, int w)
}/*bellman演算法*/
bool bellman(bellg* &g,bellv* root)
} for (i = 0; i < belle; i++)/*檢測是否有負迴路*/
if (g->e[i]->end->d > g->e[i]->start->d + g->e[i]->w)
return false;
return true;
}/*列印路徑*/
void bellprint(bellv *root, bellv *end)
}/*測試函式*/
void testbellman()
} }else
cout << "error!";
}
主函式
#include "bellman.h"
#include int main()
執行結果dijstra.h
#pragma once
#define dijv 5/*點的數量*/
#define dije 10/*邊的數量*/
/*點*/
typedef struct dijv
dijv;
/*邊*/
typedef struct
dije;
/*圖*/
typedef struct
dijg;
/*比較函式*/
bool dijcmp(dije* x, dije* y);
/*dijkstra演算法*/
void dijkstra(dijg* &g, dijv* root);
/*列印路徑*/
void dijprint(dijv *root, dijv *end);
/*測試函式*/
void testdijkstra();
dijstra.cpp
#include "dijstra.h"
#include#include#include/*sort排序函式所需標頭檔案*/
#includeusing namespace std;
/*比較函式*/
bool dijcmp(dije* x, dije* y)
/*dijkstra演算法*/
void dijkstra(dijg* &g,dijv* root)
root->mark = true;
sort(g->e, g->e + dije, dijcmp);/*按權重排序*/
j = 0;
while (j < dijv - 1)/*還有點沒有被選中*/
} }}
/*列印路徑*/
void dijprint(dijv *root, dijv *end)
}/*測試函式*/
void testdijkstra()
}}
主函式
#include "dijstra.h"
#include int main()
執行結果 《演算法導論》第24章 單源最短路徑
單元最短路徑問題 單源最短路徑問題,試 決從乙個原點到圖中其他所有點的最短路徑問題。此問題的變體有單終點最短路徑問題,單終點最短路徑問題和每對頂點間最短路徑問題。可以相應理解為一對多 多對 一 一對一和多對多的對映關係。負權值邊和負權迴路 某些權值可以是負的,這些邊稱為是負權值邊。負權迴路指的是構成...
演算法導論筆記 單源最短路徑
本文所貼示的偽 均 演算法導論 本文只是對其中 單源最短路徑 章節的簡單總結,許多數學證明過程已忽略。最短路徑的定義 給定乙個圖g v,e 希望找到從給定源節點s v 到每個結點v v 的最短路徑。單源最短路徑可以用來解決許多其他問題,包括 1 單目的地最短路徑問題 找到從每個結點v到給定目的結點t...
單源最短路徑演算法
簡單介紹 最短路徑演算法是圖演算法中的經典演算法,是用於解決圖中某個頂點到另外乙個頂點所經過路徑的花銷最小 這裡的花銷可能是時間也可能指費用等 dijkstra是用於解決單源最短路徑的經典演算法。圖的儲存方式 鄰接矩陣 在鄰接矩陣中,要獲取某個結點的出度和入讀,是通過掃瞄結點所在臨界矩陣中的行列完成...