求无向图中求两点间的所有简单路径实验报告.docx
- 文档编号:8199591
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:14
- 大小:97.98KB
求无向图中求两点间的所有简单路径实验报告.docx
《求无向图中求两点间的所有简单路径实验报告.docx》由会员分享,可在线阅读,更多相关《求无向图中求两点间的所有简单路径实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
求无向图中求两点间的所有简单路径实验报告
HUNANUNIVERSITY
课程实验报告
题目:
求无向图中求两点间的所有简单路径
学生姓名:
学生学号:
专业班级:
指导老师:
完成日期:
一.需求分析
输入形式
本程序要求用户首先输入一个结点总数,然后输入结点的城市编号(4位长的数字,例如电话区号,长沙是0731),以及高速公路连接的两所城市(用高速公路连接的两个城市编号标记),最后输入要查询所有简单路径的两座城市的名称。
当用户输入不合法时,提示用户输入有误,并重新输入。
输入具体格式如下:
请输入城市总数:
请输入高速公路的条数:
请依次输入城市名称:
请输入高速公路连接的两座城市:
请输入需查询所有路径的两所城市的名称:
输出形式
从xx到xx的所有路径如下:
将所有路径(城市编号组成)存至用户指定的文件中。
程序功能
该程序可以通过构建一个图用来表示各个城市之间是否有高速公路连通的关系,可以实现查询两城市间所有路径的功能
测试数据
请输入城市总数:
3
请依次输入城市编号:
000100020003
有几对城市间有高速公路?
3
请输入第一对连接城市的高速公路:
00010002
请输入第二对连接城市的高速公路:
00020003
请输入第三对连接城市的高速公路:
00010003
请输入请输入需查询所有路径的两所城市的名称:
00010003
从城市0001到0003的所有简单路径如下:
001->003
001->002->003
所有路径已存入文件中。
请输入城市总数:
3
请依次输入城市编号:
001002003
有几对城市间有高速公路?
2
请输入第一对连接城市的高速公路:
001002
请输入第二对连接城市的高速公路:
002003
请输入请输入需查询所有路径的两所城市的名称:
00010003
从城市0001到0003的所有简单路径如下:
001->002->003
所有路径已存入文件中。
请输入城市总数:
3
请依次输入城市编号:
001002003
有几对城市间有高速公路?
0
请输入请输入需查询所有路径的两所城市的名称:
00010003
从城市0001到0003的无简单路径
请输入城市总数:
4
请依次输入城市编号:
001002003004
有几对城市间有高速公路?
5
请输入第一对连接城市的高速公路:
001002
请输入第二对连接城市的高速公路:
002003
请输入第三对连接城市的高速公路:
003004
请输入第四对连接城市的高速公路:
001004
请输入第五对连接城市的高速公路:
001003
请输入请输入需查询所有路径的两所城市的名称:
00010004
从城市0001到0003的所有简单路径如下:
0001->0004
0001->0003->0004
0001->0002->0004
0001->0002->0003->0004
0001->0003->0002->0004
所有路径已存入文件中。
请输入城市总数:
-1
结束程序
二.概要设计
抽象数据类型
因为各个城市间的是否有高速公路连通的关系是非线性的,而且具有结构网状特性,并且高速公路是无向的,所以选择无向图来表示各个城市间的连通关系。
图的ADT设计:
数据对象:
G=(V,E),其中V表示顶点集合,E表示边集合
数据关系:
VR={
基本操作:
intn();//图中顶点个数
inte();//图边数
intfirst(int);//该点的第一条临边
intnext(int,int);//该点的第二条临边
voidsetEdge(int,int,int);//为边设置权值
voidsetMark(int,int);//设置该顶点的标志值
intgetMark(int);//获得该顶点的标志值
图的顶点ADT设计:
数据对象:
城市编号(占3位的字母数字串)
数据关系:
{vi|i=1,2,3……n}
基本操作:
intposition();//获取顶点位置
算法基本思想
当用户输入完毕后,根据各城市间相应的关系构建一个无向图,并使用一个临接矩阵存储该图。
考虑使用基于深度优先思想,在搜素过程中,每当访问一个节点,DFS就会递归访问它的所有未被访问的相邻节点。
并通过相应的设置标志的方式使最终能不重复地走遍所有的简单路径。
最后输出这些路径即可。
程序基本流程
该程序主要包括四个模块:
输入模块:
由用户输入城市总数,城市编号,高速公路编号;
构建与存储模块:
根据用户的输入构建无向图,并使用临接矩阵存储图;
访问模块:
对该图进行深度优先搜索,得到所有路径;
输出模块:
输出所有路径。
三.详细设计
物理数据类型
边的实现:
classEdge
{
public:
intvertex,weight;
Edge(){vertex=-1;weight=-1;}
Edge(intv,intw){vertex=v;weight=w;}
};
图的相邻矩阵实现:
classGraphm
{
private:
intnumVertex,numEdge;
int**matrix;
int*mark;
public:
Graphm(intnumVert){
inti,j;
numVertex=numVert;//顶点数
numEdge=0;
mark=newint[numVert];
for(i=0;i mark[i]=0;//每一个顶点的标志值初始化为0 matrix=(int**)newint*[numVertex]; for(i=0;i matrix[i]=newint*[numVertex];for(i=0;i for(j=0;j } ~Graphm() { delete[]mark; for(inti=0;i delete[]matrix[i]; delete[]matrix;}//析构函数 intn(){returnnumVertex;}//顶点个数 intfirst(intv)//该顶点的第一条邻边 { inti; for(i=0;i if(matrix[v][i]! =0)returni; returni; } intnext(intv1,intv2)//获得v1的邻居v2 {inti; for(i=v2+1;i if(matrix[v1][i]! =0)returni; returni;} voidsetEdge(intv1,intv2)//设置有向图的边 { if(matrix[v1][v2]==0) numEdge++; matrix[v1][v2]=1; } intgetMark(intv)//获取顶点标记的值 {returnmark[v];} intsetMark(intv,intval)//设置访问的标记{mark[v]=val;} } DFS的实现: voidDFS(Graph*G,intv) { PreVisit(G,v); G->setMark(v,1); for(intw=G->first(v);w if(G->getMark(w)==0) DFS(G,w); PostVisit(G,v); } 算法具体步骤 根据用户的输入,构建一个无向图,并使用一个临接矩阵存储该图。 对该图进行深度优先搜索,并通过相应的设置标志的方式使最终能不重复地走遍所有的简单路径。 得到所有路径后,输出这些路径即可。 函数调用关系 输入 建图与存图临接矩阵存储 主程序DFS搜索 输出 算法时空分析 在表的存储中,临接矩阵的时间代价是Θ(|V2|),而在无向图中,DFS从两个方向处理每条边,每个顶点都必须被访问,且只能被访问一次,因此时间代价是Θ(|V|+|E|)。 所以该算法总时间代价是Θ(|V|2)。 输入输出格式 输入: cin>>cityNum; for(inti=0;i cin>>city[i]; cin>>roadNum; for(i=0;i { cin>>roadName; } 请输入城市总数: 3 请依次输入城市编号: 001002003 有几对城市间有高速公路? 3 请输入第一对连接城市的高速公路: 001002 请输入第二对连接城市的高速公路: 002003 请输入第三对连接城市的高速公路: 001003 请输入要查询路径的两座城市编号: 001003 输出: 001到003的所有路径如下: 001->003 001->002->003 所有路径已存入文件中。 四.调试分析 在实际编程中,程序曾陷入过死循环,尝试了一些方法仍然没有解决,最后使用了goto语句才解决了这个问题 五.测试结果 六.用户使用说明 1.该程序可以通过构建一个有向图来实现查找两城市间的所有简单路径的功能; 2.使用该程序时,首先按照要求输入各类参数,若输入有误,系统提示输入有误,并重新输入; 3.最后的结果将直接输出在DOS界面。 七.实验心得 通过该实验,我掌握了图的深度优先搜索的方法 代码: graph.h文件: #include #include #include usingnamespacestd; boolvisited[100]; intpath[100]; classArcNode { public: intadjvex; ArcNode*nextarc; }; classVexNode { public: stringdata; ArcNode*firstarc; }; classGraph { private: VexNodevertices[100]; intvexnum; intarcnum; public: Graph() { vexnum=0; arcnum=0; } ~Graph(){delete[]vertices;} intgetArcnum() { returnarcnum; } intGetVexNum() { returnvexnum; } intPosition(stringv) { for(inti=0;i if(vertices[i].data==v) returni; return-1; } voidBuild_Graph() { //构造无向图 stringv1,v2; inti,j,k; cout<<"输入城市个数: "; cin>>vexnum; cout<<"请输入高速公路的条数: "; cin>>arcnum; cout<<"输入城市名称: "; for(i=0;i { cin>>vertices[i].data; vertices[i].firstarc=NULL; } for(k=0;k { cout<<"输入每条高速公路连接的两座城市: "; cin>>v1>>v2; i=Position(v1); j=Position(v2); while(i==-1||j==-1) { cout<<"输入有误,请重新输入: "; cin>>v1>>v2; i=Position(v1); j=Position(v2); } ArcNode*p=newArcNode; p->adjvex=j; p->nextarc=vertices[i].firstarc; vertices[i].firstarc=p; //置对称边 ArcNode*q=newArcNode; q->adjvex=i; q->nextarc=vertices[j].firstarc; vertices[j].firstarc=q; } } voidPrint_Road(intu,intv,intl,intd) { //求出一条长度为l的从u到v的路径 inti=0; intm; d++; visited[u]=true; path[d]=u; if(u==v&&d==l){ for(i=0;i cout< cout< } elseif(u==v&&d! =l) { //出现这种情况直接回溯上一顶点 gotoloop; } ArcNode*p=vertices[u].firstarc; while(p) { m=p->adjvex; if(! visited[m]) Print_Road(m,v,l,d); p=p->nextarc; } //路径长度减一 loop: visited[u]=false; d--; } }; Main.cpp #include"graph.h" #include #include usingnamespacestd; intmain() { GraphG; stringcity1,city2; intpos1,pos2; G.Build_Graph();//建图 cout<<"请输出两座城市的名称: "; cin>>city1>>city2; pos1=G.Position(city1);//第一所城市的位置 pos2=G.Position(city2);//第二所城市的位置 if(pos1==-1||pos2==-1) { cout<<"顶点中有不符合要求的,操作失败"< } else { for(inti=0;i visited[i]=false; } cout<<"城市"< "< for(intj=1;j<=G.getArcnum();j++) G.Print_Road(pos1,pos2,j,-1);//输出两座城市间的所有简单路径 system("pause>>NUL"); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图中求 两点 所有 简单 路径 实验 报告
