实验报告
课程名称 《算法分析与设计》
实验日期 2021年 3 月 15 日 至 2021年 3 月 21日
学生姓名 zjk 所在班级 计算机194
实验名称 实验二:Floyd以及Dijkstra算法
实验地点 同组人员 无
2.1问题
用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵)。
-
解析
概念:Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。
算法思路:1。从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
2。对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
3.把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。 -
设计
[核心伪代码]
int D[max][max]={/输入最初的距离矩阵/}; //表示图中各个节点之间的路径,如D[i][j],就为Vi——>Vj权值为D[i][j]
int S[max][max]; //表示图中节点的后继矩阵,如S[i][j],则Vi——>Vj的最短路径的存在V S[i][j].
for(i到V){ //对S进行初始化
count=0;
for(j到V){
if(i!=j){
S[i][j]=count;
}
else{
S[i][j]=-1;
}
++count;
}
}
for(k到V) //V表示节点的数量
for(i到V)
for(j到V)
if(D[i][k]+D[k][j]<D[i][j]){
D[i][j]=D[i][k]+D[k][j];
S[i][j]=S[i][k];
}
for(i到V){
for(j到V)
//输出距离矩阵。
} -
分析
[算法复杂度推导]
由上伪代码设计可得,
时间复杂度:O(n^3);
空间复杂度:O(n^2) 。 -
[github源码地址]
2.2问题
对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径.
1解析
概念:Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
操作:
1.声明一个数组k来保存源点到各个顶点的最短距离,集合T保存已经找到了最短路径的顶点,初始原点 s 的路径权重被赋为 0 (k[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把k[m]设为w(s, m),同时把所有其他顶点的路径长度设为无穷大。初始时,集合T只有顶点s。
2.然后,从k数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,此时完成一个顶点。之后我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在k中的值。
3.最后,又从k中找出最小值,重复上述动作,直到T中包含了图的所有顶点。
2设计
【核心伪代码】
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y]=z;
a[y][x]=z;
}
for( i=1; i<=n; i++)
d[i]=max1;
d[1]=0;
for(i=1;i<=n;i++)
{
min1 = max1;
// for循环用于找到未访问节点中d[j]值最小的那个节点,用k标记
for(j=1;j<=n;j++)
if(!p[j]&&d[j]<min1)
{
min1=d[j];
k=j;
}
p[k] = 1; //表示第k个节点访问过
for(j=1;j<=n;j++)
if(a[k][j]!=0&&!p[j]&&d[j]>d[k]+a[k][j])
d[j]=d[k]+a[k][j];
}
3 分析
时间复杂度为O(N^3)。
4.[github源码地址]
https://github.com/zjk715/–homework