动态规划之任意顶点间最短距离
来源:互联网 发布:什么是微观数据 编辑:程序博客网 时间:2024/06/03 13:33
A,动态规划思想:假设带权有向图G中的任意编号为(V1,V2,V3,...,Vn),如果 Vi到Vj的最短路径是d(i,j),那么对于路径上任一中间节点k,d(i,k)与d(k,j)都是最短路径。Vi到Vj的最短路径要么经过k,要么不经过k,就如同动态规划解矩阵连乘问题一样,我们只要从i到j枚举k,有j-i个选择,但是矩阵加括号后,其子问题之间不会有交点。对于图而言,如果不加限制d与d可能会有交集,因此我们这样处理:
上述就是下面将要介绍的floyd-warshall算法的思想。
B,算法原理:
1)算法中有两个数组path,A,其中A[i][j]代表Vi到Vj经过的路径的最小代价,path[i][j]表示Vi到Vj经过的中间节点k;2)要计算A[i][j],就首先计算A[i][k]和A[k][j],其中A[i][k]和A[k][j]没有交点;
3)循环图中的每个节点,并先假设将每次循环的节点k作为图中任意两个节点最短路径之间的中间节点;
4)如果图中任意两个节点Vi到Vj经过k节点后代价更小,则使k作为Vi到Vj的中间节点,否则Vi到Vj不需要经过k;
5)直到遍历完每个节点(即每个节点都作为“桥”之后),算法结束。
下图为该算法处理四个节点的有向图的过程:
#include "iostream"
using namespace std;
typedef char VertexType;//定义邻接矩阵节点的类型
#define MAXIMUM 65535//无穷大
#define MAXVEX 50//图中最大节点数
typedef struct //定义邻接矩阵的数据结构
{
VertexType vexs[MAXVEX];
int edges[MAXVEX][MAXVEX];
int vexNum, adgeNum;//分别表示图中节点个数和边的条数
}AGraph;
int main()
{
void createAGraph(AGraph*);
void floydPath(int A[][MAXVEX], int path[][MAXVEX],int);
void printPath(int, int, int[][MAXVEX], AGraph *);
int A[MAXVEX][MAXVEX], path[MAXVEX][MAXVEX];
AGraph g;
createAGraph(&g);
for(int i = 0; i < g.vexNum; ++i)
for(int j = 0; j
{
path[i][j] = -1;
A[i][j] = g.edges[i][j];
}
floydPath(A, path, g.vexNum);
while(true)
{
int m,n;
cout<<"请输入任意两个顶点序号i,j:";
cin>>m>>n;
cout<<g.vexs[m]<<"->";
printPath(m, n, path, &g);
cout<<g.vexs[n]<<endl;
}
return 0;
}
//输出任意两点之间的最短路径
void printPath(int i, int j, int path[][MAXVEX], AGraph*g)
{
int k = path[i][j];
if(-1 == k)
return;
printPath(i, k, path, g);
cout<<g->vexs[k]<<"->";
printPath(k, j, path, g);
}
//Floyd算法求解任意顶点间的最短路径
void floydPath(int A[][MAXVEX], int path[][MAXVEX], intn)
{
for(int k = 0; k < n; ++k)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; ++j)
{
if(A[i][k] + A[k][j] < A[i][j])
{
A[i][j] = A[i][k] + A[k][j];
path[i][j] = k;
}
}
}
void createAGraph(AGraph *g)//创建图的邻接矩阵
{
int vNum, aNum;//分别代表要创建的图的节点数和边数
int start, end;//start->end表示节点start和end之间有一条边
int weight;//边的权重
cout<<"请输入图中节点的个数和边的条数:";
cin>>vNum>>aNum;
printf("\n请输入%d个节点的信息:", vNum);
//创建节点
for(int i = 0; i < vNum; ++i)
{
cin>>g->vexs[i];
}
cout<<"这里输出节点编号及其存储的节点信息"<<endl;
for(int k = 0; k < vNum; ++k)
cout<<k<<":"<<g->vexs[k]<<"";
cout<<endl;
//初始化边信息
for(int m = 0; m < vNum; ++m)
for(int n = 0; n < vNum; ++n)
{
if(m == n)
g->edges[m][n] = 0;
else
g->edges[m][n] = MAXIMUM;
}
//创建无向图的边信息
for(int j = 0; j < aNum; ++j)
{
cout<<"\n请输入第"<<j+1<<"条边的start和end节点和边的权值weight:";
cin>>start>>end>>weight;
g->edges[start][end] = weight;
}
//初始化vexNum和adgeNum
g->vexNum = vNum;
g->adgeNum = aNum;
}
运行结果:
D,算法复杂度
时间复杂度:Floyd算法求最短路径是有三层循环嵌套,时间复杂度为O(n^3)。
0 0
- 动态规划之任意顶点间最短距离
- 动态规划之最短距离
- 字符串间最短距离(动态规划)
- 字符串间最短距离(动态规划)
- 算法之美——求解 字符串间最短距离(动态规划)
- 算法之美——求解 字符串间最短距离(动态规划)
- 字符串最短距离CalculateStringDistance(递归 or 动态规划)
- 【动态规划】每对顶点之间的最短路径之Floyd-Warshall算法
- Floyd 任意两点间的最短距离 dp
- 图论之两点间最短距离
- 任意两节点之间最短距离
- 每对顶点间的最短距离 Floyd_Warshall算法 C++实现
- 每对顶点间的最短距离——floyd算法
- hdu 1217 Arbitrage(floyd 每对顶点间的“最短距离”)
- 每对顶点间的最短距离 Floyd_Warshall算法 C++实现
- 求任意两个顶点间的最短路径
- 求图中任意两个顶点间的最短路径
- 第25章:每对顶点间的最短路径—基于矩阵乘法的动态规划算法
- 查找算法之折半搜索算法
- 树的遍历
- 免安装版tomcat自启动
- 图的遍历
- 动态规划之矩阵连乘问题
- 动态规划之任意顶点间最短距离
- 贪心法之背包问题
- 贪心法之最小生成树之Kruskal算法
- 贪心法之最小生成树之Prim算法
- 贪心法之最短路径之Dijkstra算法
- Node.js学习总结(一)
- js实现滚动文本显示
- 拼图最后两张图片异位问题的解决
- 分支限界法之最大团问题