数据结构:点对之间最短距离--Floyd算法
来源:互联网 发布:java类声明 编辑:程序博客网 时间:2024/06/18 18:48
Floyd算法
Floyd算法
Dijkstra算法是用于解决单源最短路径问题的,Floyd算法则是解决点对之间最短路径问题的。Floyd算法的设计策略是动态规划,而Dijkstra采取的是贪心策略。当然,贪心算法就是动态规划的特例。
算法思想
点对之间的最短路径只会有两种情况:
- 两点之间有边相连,weight(Vi,Vj)即是最小的。
- 通过另一点:中介点,两点相连,使weight(Vi,Vv)+weight(Vv,Vj)最小。
Min_Distance(Vi,Vj)=min{weight(Vi,Vj),weight(Vi,Vv)+weight(Vv,Vj)}。正是基于这种背后的逻辑,再加上动态规划的思想,构成了Floyd算法。故当Vv取完所有顶点后,Distance(Vi,Vj)即可达到最小。Floyd算法的起点就是图的邻接矩阵。
题外话:代码本身不重要,算法思想才是精髓。思想极难得到,而有了思想,稍加经验即可写出代码。向思想的开创者致敬!
思想很难,代码却比较简单,直接上代码
代码
类定义
#include<iostream> #include<iomanip>#include<stack>using namespace std;#define MAXWEIGHT 100#undef INFINITY#define INFINITY 1000class Graph{private://顶点数 int numV;//边数 int numE;//邻接矩阵 int **matrix;public:Graph(int numV);//建图 void createGraph(int numE);//析构方法 ~Graph();//Floyd算法void Floyd();//打印邻接矩阵 void printAdjacentMatrix();//检查输入 bool check(int, int, int);};类实现
//构造函数,指定顶点数目Graph::Graph(int numV){//对输入的顶点数进行检测while (numV <= 0){cout << "顶点数有误!重新输入 ";cin >> numV;}this->numV = numV;//构建邻接矩阵,并初始化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;elsematrix[i][j] = INFINITY;}}void Graph::createGraph(int numE){/*对输入的边数做检测一个numV个顶点的有向图,最多有numV*(numV - 1)条边*/while (numE < 0 || numE > numV*(numV - 1)){cout << "边数有问题!重新输入 ";cin >> numE;}this->numE = numE;int tail, head, weight, i;i = 0;cout << "输入每条边的起点(弧尾)、终点(弧头)和权值" << 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(){//为了不修改邻接矩阵,多用一个二维数组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数组int **prev = new int*[numV];for (i = 0; i < numV; i++)prev[i] = new int[numV];//初始化prevfor (i = 0; i < numV; i++)for (j = 0; j < numV; j++){if (matrix[i][j] == INFINITY)prev[i][j] = -1;elseprev[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数组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;}主函数
int main(){cout << "******Floyd***by David***" << endl;int numV, numE;cout << "建图..." << endl;cout << "输入顶点数 ";cin >> numV;Graph graph(numV);cout << "输入边数 ";cin >> numE;graph.createGraph(numE);cout << endl << "Floyd..." << endl;graph.Floyd();system("pause");return 0;}运行
小结
Floyd算法代码看似很长,其实并不难。代码中很多都是用于准备工作和输出,关键代码就是三层for循环。
完整代码下载:Floyd算法
转载请注明出处,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/38366923
若有所帮助,顶一个哦!
专栏目录:
- 数据结构与算法目录
- c指针
1 0
- 数据结构:点对之间最短距离--Floyd算法
- 数据结构:点对之间最短距离--Floyd算法
- (1.2.6.7)点对之间最短距离--Floyd算法
- Floyd算法,求图中两个点之间的最短距离
- Floyd算法(求每一对顶点之间的最短距离)
- Floyd(各对顶点之间的最短距离)
- 最短距离 dijkstra floyd 算法
- Floyd-Warshall算法(最短距离)
- UVa10075 - Airlines(所有点对之间的最短距离)
- floyd算法 多源路径最短距离
- Floyd算法求所有点对之间的最短路径
- UVa:567 Risk (Floyd算法求所有顶点之间的最短距离模版题)
- 每对顶点间的最短距离——floyd算法
- HDU1007 求最短距离的点对
- 迪杰斯特拉算法 计算两点之间最短距离
- 点到线段最短距离的算法
- 点到线段的最短距离算法
- 点到线段的最短距离算法
- 对Mahout_"推荐算法"的初步认识(5)_研讨篇
- MD5 加密方法
- basket nike tn pas cher or with a towel
- Cocos2d-x 3.0心得(05)-音效管理
- Ray Ban France the captain closed the door after five people blocking up the plane took off more th
- 数据结构:点对之间最短距离--Floyd算法
- 冒泡排序
- Android 横竖屏的锁定
- WiFi Display
- oracle 10g函数大全--分析函数
- spring+ibatis【基本配置及动态sql】
- Android中onInterceptTouchEvent与onTouchEvent
- OpenWRT 增加内核模块及应用方法
- UNIX环境高级编程 apue.h头文件的配置