日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构:点之间的最短距离--Floyd算法

發(fā)布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构:点之间的最短距离--Floyd算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? ? ? ? ? ? ? ? ? ? ?Floyd算法

Floyd算法

? ? Dijkstra算法是用于解決單源最短路徑問題的,Floyd算法則是解決點對之間最短路徑問題的。Floyd算法的設(shè)計策略是動態(tài)規(guī)劃,而Dijkstra採取的是貪心策略。當(dāng)然,貪心算法就是動態(tài)規(guī)劃的特例。

算法思想

? ? 點對之間的最短路徑僅僅會有兩種情況:

  • 兩點之間有邊相連。weight(Vi,Vj)即是最小的。

  • 通過還有一點:中介點,兩點相連,使weight(Vi,Vv)+weight(Vv,Vj)最小。

  • Min_Distance(Vi,Vj)=min{weight(Vi,Vj),weight(Vi,Vv)+weight(Vv,Vj)}。正是基于這樣的背后的邏輯。再加上動態(tài)規(guī)劃的思想,構(gòu)成了Floyd算法。

    故當(dāng)Vv取全然部頂點后,Distance(Vi,Vj)就可以達(dá)到最小。Floyd算法的起點就是圖的鄰接矩陣。


    題外話:代碼本身不重要。算法思想才是精髓。

    思想極難得到,而有了思想,稍加經(jīng)驗就可以寫出代碼。向思想的開創(chuàng)者致敬。


    思想非常難。代碼卻比較簡單。直接上代碼

    代碼

    類定義 #include<iostream> #include<iomanip> #include<stack> using namespace std; #define MAXWEIGHT 100 #undef INFINITY #define INFINITY 1000 class Graph { private://頂點數(shù) int numV;//邊數(shù) int numE;//鄰接矩陣 int **matrix; public:Graph(int numV);//建圖 void createGraph(int numE);//析構(gòu)方法 ~Graph();//Floyd算法void Floyd();//打印鄰接矩陣 void printAdjacentMatrix();//檢查輸入 bool check(int, int, int); };類實現(xiàn) //構(gòu)造函數(shù),指定頂點數(shù)目 Graph::Graph(int numV) {//對輸入的頂點數(shù)進行檢測while (numV <= 0){cout << "頂點數(shù)有誤!

    又一次輸入 "; cin >> numV; } this->numV = numV; //構(gòu)建鄰接矩陣。并初始化 matrix = new int*[numV]; int i, j; for (i = 0; i < numV; i++) matrix[i] = new int[numV]; for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { if (i == j) matrix[i][i] = 0; else matrix[i][j] = INFINITY; } } void Graph::createGraph(int numE) { /* 對輸入的邊數(shù)做檢測 一個numV個頂點的有向圖,最多有numV*(numV - 1)條邊 */ while (numE < 0 || numE > numV*(numV - 1)) { cout << "邊數(shù)有問題!又一次輸入 "; cin >> numE; } this->numE = numE; int tail, head, weight, i; i = 0; cout << "輸入每條邊的起點(弧尾)、終點(弧頭)和權(quán)值" << endl; while (i < numE) { cin >> tail >> head >> weight; while (!check(tail, head, weight)) { cout << "輸入的邊不對!請又一次輸入 " << endl; cin >> tail >> head >> weight; } matrix[tail][head] = weight; i++; } } Graph::~Graph() { int i; for (i = 0; i < numV; i++) delete[] matrix[i]; delete[]matrix; } /* 弗洛伊德算法 求各頂點對之間的最短距離 及其路徑 */ void Graph::Floyd() { //為了不改動鄰接矩陣,多用一個二維數(shù)組 int **Distance = new int*[numV]; int i, j; for (i = 0; i < numV; i++) Distance[i] = new int[numV]; //初始化 for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) Distance[i][j] = matrix[i][j]; //prev數(shù)組 int **prev = new int*[numV]; for (i = 0; i < numV; i++) prev[i] = new int[numV]; //初始化prev for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { if (matrix[i][j] == INFINITY) prev[i][j] = -1; else prev[i][j] = i; } int d, v; for (v = 0; v < numV; v++) for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { d = Distance[i][v] + Distance[v][j]; if (d < Distance[i][j]) { Distance[i][j] = d; prev[i][j] = v; } } //打印Distance和prev數(shù)組 cout << "Distance..." << endl; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) cout << setw(3) << Distance[i][j]; cout << endl; } cout << endl << "prev..." << endl; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) cout << setw(3) << prev[i][j]; cout << endl; } cout << endl; //打印頂點對最短路徑 stack<int> s; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) { if (Distance[i][j] == 0); else if (Distance[i][j] == INFINITY) cout << "頂點 " << i << " 到頂點 " << j << " 無路徑!

    " << endl; else { s.push(j); v = j; do{ v = prev[i][v]; s.push(v); } while (v != i); //打印路徑 cout << "頂點 " << i << " 到頂點 " << j << " 的最短路徑長度是 " << Distance[i][j] << " ,其路徑序列是..."; while (!s.empty()) { cout << setw(3) << s.top(); s.pop(); } cout << endl; } } cout << endl; } //釋放空間 for (i = 0; i < numV; i++) { delete[] Distance[i]; delete[] prev[i]; } delete[]Distance; delete[]prev; } //打印鄰接矩陣 void Graph::printAdjacentMatrix() { int i, j; cout.setf(ios::left); cout << setw(7) << " "; for (i = 0; i < numV; i++) cout << setw(7) << i; cout << endl; for (i = 0; i < numV; i++) { cout << setw(7) << i; for (j = 0; j < numV; j++) cout << setw(7) << matrix[i][j]; cout << endl; } } bool Graph::check(int tail, int head, int weight) { if (tail < 0 || tail >= numV || head < 0 || head >= numV || weight <= 0 || weight >= MAXWEIGHT) return false; return true; }

    主函數(shù) int main() {cout << "******Floyd***by David***" << endl;int numV, numE;cout << "建圖..." << endl;cout << "輸入頂點數(shù) ";cin >> numV;Graph graph(numV);cout << "輸入邊數(shù) ";cin >> numE;graph.createGraph(numE);cout << endl << "Floyd..." << endl;graph.Floyd();system("pause");return 0; }執(zhí)行


    小結(jié)

    Floyd算法代碼看似非常長,事實上并不難。代碼中非常多都是用于準(zhǔn)備工作和輸出。關(guān)鍵代碼就是三層for循環(huán)。


    完整代碼下載:Floyd算法

    轉(zhuǎn)載請注明出處,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/38366923
    若有所幫助,頂一個哦。

    專欄文件夾:
    • 數(shù)據(jù)結(jié)構(gòu)與算法文件夾
    • c指針

    版權(quán)聲明:本文博主原創(chuàng)文章。轉(zhuǎn)載,轉(zhuǎn)載請注明出處。

    轉(zhuǎn)載于:https://www.cnblogs.com/gcczhongduan/p/4850988.html

    總結(jié)

    以上是生活随笔為你收集整理的数据结构:点之间的最短距离--Floyd算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。