1.问题引入
现在人们出行用滴滴就特别方便。在滴滴上我们打到车后在司机的手机上就会选择到目的地最短的一条路径。那在软件中这个最短的路径是怎么产生的呢?
这儿就来介绍产生最短路径的两种方法:
Dijkstra 和Floyd
最短路径:源点到终点的距离最短的路径(在这儿体现为: 源点到终点路径上边的权值之和)
Dijkstra 和Floyd
这两个算法及其相似;
我自己将它门分别归为二维操作和三维操作。
S 集合:已经求出的最短路径顶点集合
Dijkstra的最短路径推导过程中:
1. 先找到起点
2. 然后从起点选择到其他顶点的可达路径
3. 然后选择到(除开S集中的顶点)权值最小的路径指向的顶点作为下一步的起点、并且将指向的顶点加入到 已经求出的最短路径顶点集合S里
4. 又到第二步,直到n个结点全部求出
Dijkstra算法:
这是一个单源点算法:单源点就是一个起点的啦!
处理的是:带权有向图
存储:邻接矩阵
思想是:依照路径长度递增的次序来产生最短路径
typedef struct {
Matrix[][];//邻接矩阵
vexnum;//顶点数目
arcnum;//边数目
type;//矩阵类型
}Graph;
int *Dijkstra_fun(Graph Graph,int begin){
for(v=0;Graph.vexnum;++v)
{
finial[v] = false;//顶点是否在S集合中 S集合(已经求得的最短路径终点集合)
Distance[v] = Graph.Matrix[begin][v]; //begin是起点
}
finial[begin] = true;
Distance[begin] = 0;//初始化 将begin顶点加入到S集合中 begin顶点到本身路径长度为0
for(i=1;i<Graph.vexnum;++i)
{
min = INT_MAX;
for(w=0;w<Graph.vexnum;++w)
if( !finial[w] )//不在S集合中
if(Distance[w] < min)
{
p =w;//暂存顶点w
min = Distance[w]; //该顶点的值赋给最小值
}
finial[w] = true;//w顶点加入到finial中
for(w=0;w<Graph.vexnum;++w)
if(!finial[w] && Distance[w] > ( min + Graph.Matrix[p][w]))
Distance[w] = min + Graph.Matrix[p][w];
}
return Distance
}
一个例子:
Floyd算法:
一对顶点之间的的最短路径处理:
1. Dijkstra算法调用n次 ,T(n) = O(n^3),因为 Dijkstra算法复杂度为O(n^2)
2. Floyd算法
针对一对顶点的最短路径计算
for(mid = 0 ; mid < G.vexnum ; ++mid)
for(front = 0 ; front < G.vexnum ; ++front)
for(rear = 0 ; rear < G.vexnum ; ++rear)
if(G.matrix[front][rear] > (G.matrix[front][mid] + G.matrix[mid][rear]))
G.matrix[front][rear] = G.matrix[front][mid] + G.matrix[mid][rear];
//动态规划思想
//邻接矩阵表示
//可看做G[mid][front][rear]
//G的最外层可省略:因为G[k]只和G[k-1]有关
//G[0]等于最初图的邻接矩阵
未完待续(初稿1)