最短路径规划实验报告
一、图的定义和术语
图是一种数据结构。
ADT Graph{
数据对象V:V是据有相同特性的数据元素的集合,称为顶点集。
数据关系R:
R={VR}
VR={<v,w>|v,w∈V且P(v,w), <v,w>表示从v到w的弧,P(v,w)定义了弧<v,w>的意义或信息}
图中的数据元素通常称为顶点,V是顶点的有穷非空集合;VR是两个顶点之间的关系的集合,若顶点间是以有向的弧连接的,则该图称为有向图,若是以无向的边连接的则称为无向图。弧或边有权值的称为网,无权值的称为图。
电子科技大学计算机学院
标准实验报告
(实验)课程名称最短路径规划
电子科技大学教务处制表
实验报告
学生姓名:李彦博学号:2902107035指导教师:陈昆
一、实验项目名称:最短路径规划
二、实验学时:32学时
三、实验原理:Dijkstra算法思想。
四、实验目的:实现最短路径的寻找。
五、实验内容:
1、图的基本概念及实现。
分析:实验准确找到了从V1出发的到各点的最短路径及权值,实现了最短路径的规划。
九、实验结论:
通过Dijkstra算法思想快速准确的实现了最短路径的规划。
十、总结及心得体会:
通过最短路径规划实验课的学习,进一步巩固了我的c语言知识,而且了解了Dijkstra算法思想,掌握了怎样实现最短路径规划及实现最短路径规划的意义。
final[v]=TRUE;a[i-1]=v+1; //离V0顶点最近的V加入S集
for(w=0;w<g.vexnum;++w) //更新当前最短路径及距离
if(!final[w]&&(min+g.arcs[v][w])<d[w]){//修改D[w]和p[w],wn属于V-S
d[w]=min+g.arcs[v][w];
printf("经过的点为: V1 ");
{for(j=0;j<5;j++)
for(k=0;k<6;k++)
if(p[i][k]==TRUE && a[j]==(k+1)) printf("V%d\t",a[j]);
}
printf("\n");
};
}
八、实验数据及结果分析:
数据:V1到各点的最短路径及权值分别为:V1→V2,权值:5;V1→V2→V3,权值:9;V1→V4,权值:7;V1→V4→V6→V5,权值:14;V1→V4→V6,权值:13.
二、算法描述
1)arcs[i,j]表示弧<vi,vj>上的权值。若<vi,vj>不存在,则置arcs[i,j]为∞(在本程序中为MAXCOST)。S为已找到从v出发的最短路径的终点的集合,初始状态为空集。那么,从v出发到图上其余各顶点vi可能达到的最短路径长度的初值为D[i]=arcs[Locate Vex(G,v),i] vi∈V
for(k=0;k<6;k++)p[w][k]=p[v][k];
p[w][w]=TRUE;
}
}
printf("\n");
printf("\n对应最短路径为:\n");
printf("\n"); //美化格式
for(i=1;i<6;i++)
{ printf("从V1点到V%d点的最短路径长为:",i+1);printf("%d\t",d[i]);
{
k=i+1;
printf("V%d",k);
for(j=0;j<6;j++)
{
if(g.arcs[i][j]>99)
printf("max");
else
printf("%d",g.arcs[i][j]);
}
printf("\n");
}
//用Dijkstra算法求有向网的v0点到其余各点v的最短路径P[v]及其带权长度D[v].
报告评分:
指导教师签字:
几点注意事项:
1.封面统一到教务处购买;
2.实验报告的各项标题和源程序需要打印,其他内容必须手写(不能用圆珠笔);
3.除最后一项外,其余各项必须填写。
那么,下一条长度次短的最短路径是哪一条呢?假设该次短路径的终点是vk,则可想而知,这条路径或者是(v,vk),或者是(v,vj,vk)。它的长度或者是从v到vk的弧上的权值,或者是D[j]和从vj到vk的弧上的权值之和。
一般情况下,假设S为已求得最短路径的终点的集合,则可证明:下一条最短路径(设其终点为X)或者是弧(v,x),或者是中间只经过S中的顶点而最后到达顶点X的路径。因此,下一条长度次短的最短路径的长度必是D[j]=Min{D[i] | vi∈V-S}其中,D[i]或者是弧(v,vi)上的权值,或者是D[k](vk∈S)和弧(vk,vi)上的权值之和。
Int vexnum,arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
}MGraph;
1.练习:构造一个有向网。
2、Dijkstra算法思想及实现。
一、算法思想
首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的最短路径的长度。如D[3]=2表示从始点v到终点3的路径相对最小长度为2。这里强调相对就是说在算法过程中D[i]的值是在不断逼近最终结果但在过程中不一定就等于最短路径长度。它的初始状态为:若从v到vi有弧,则D[i]为弧上的权值;否则置D[i]为∞。显然,长度为D[j]=Min{D[i] | vi∈V}的路径就是从v出发的长度最短的一条最短路径。此路径为(v,vj)。
七、实验步骤:
程序:
#include<stdio.h>
#define m 100
#define TRUE 1
#define FALSE 0
typedef struct Cel{
int arcs[6][6]; //邻接矩阵
int vexnum;
};
void main()
{
int d[6],p[6][6],v,w,final[6],i,j,k,min,a[5]={1,1,1,1,1},n,z,x,c,b;
//对带权图,则为权值类型。
InfoType *info; //弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
Typedef struct{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix EX_NUM 20 //最大顶点个数
Typedef enum{DG,DN,UDG,UDN} GraphKind; //有向图,有向网,无向图,无向网
Typedef struct ArcCell{
VRType adj; //顶点关系类型,对无权图,有1或0表示是否相邻;
2)选择vj,使得D[j]=Min{D[i] | vi∈V-S}
3)修改从v出发到集合V-S上任一顶点vk可达的最短路径长度。如果D[j]+arcs[j,k]<D[k]则修改D[k]为D[k]=D[j]+arcs[j,k]。
4)重复2)和3),直到找到目标顶点或遍历所有顶点为止。
六、实验器材(设备、元器件):电脑
//若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。其中w为经过的顶点。
//final[v]为TRUE当且仅当v在s中,即已经求得从v0到v的最短路径。
//初始化
for (v=0;v<g.vexnum;++v){
final[v]=FALSE; d[v]=g.arcs[0][v];
for(i=1;i<g.vexnum;++i)
{ //其余g.vexnum-1个顶点
min=m; //当前所知离V0顶点的最近距离
for(w=0;w<g.vexnum;++w)
if(!final[w]) //w顶点在V-S中
if(d[w]<min){v=w;min=d[w];} //W顶点离V0更近
Cel g={ m,5,m,7,m,m,
m,m,4,m,m,m,
8,m,m,m,m,9,
m,m,5,m,m,6,
m,m,m,5,m,m,
3,m,m,m,1,m,
6};
printf("对应的矩阵为:\n");
printf("\n");
printf("V1V2V3V4V5V6\n"); //美化格式
for(i=0;i<6;i++)
二、图的存储结构
邻接表、邻接多重表、十字链表和数组。这里我们只介绍数组表示法。
图的数组表示法:
用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息。其形式描述如下:
//---------图的数组(邻接矩阵)存储表示----------
#define INFINITY INT_MAX //最大值
for (w=0;w<g.vexnum;++w) p[v][w]=FALSE;//设空路径
if(d[v]<m){p[v][0]=TRUE; p[v][v]=TRUE;}
}
d[0]=0; final[0]=TRUE; //初始化,V0顶点属于S