五叉路口交通灯的管理系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计报告五叉路口交通灯的管理系统
学生姓名:
专业:
班级:
学号:
指导教师:
2017年5月5日
目录
一、实验题目 (2)
二、实验目的 (2)
三、实验要求 (2)
四、实现过程 (3)
1、问题分析: (3)
2、详细设计: (3)
3、调试分析: (10)
4、运行结果: (11)
5、实验总结: (13)
五、参考文献 (14)
六、附录 (14)
一、实验题目
五叉路口交通灯的管理系统
二、实验目的
(1)构造解决实际问题的图的模型。

(2)熟悉邻接矩阵和邻接表这两种存储结构的特点及适用范
围,能够根据应用问题的特点和要求,选择合适的存储结构。

(3)掌握图顶点的着色问题及其解决方法。

三、实验要求
1.[问题描述]:
设计一个交通信号灯的管理系统:一个五叉路口如下图所示,在这个路口共有 5 条道路相交,其中 C 和 E 是单行线,其他为双行线。

在该路口需要设置几种颜色的交通灯才能既使车辆相互之间不碰撞,又能达到车辆的最大流通?
图1.1
2.[数据结构]
本课程设计使用的数据结构是邻接表和邻接矩阵。

四、实现过程
1、问题分析:
为了设计一个交通信号灯的管理系统,首先需要分析一下所有车辆的行驶路线的冲突问题。

这个问题可以归结为对车辆的可能行驶路线作某种分组,对分组的要求是使任一个组中各个方向行驶的车辆可以同时安全行驶而不发生碰撞。

显然,对这个路口存在许多不同分组方案,而如果分组数越少,则可以同时行驶的车辆也就越多,从而使管理系统的质量越高。

2、详细设计:
1.建立模型
根据这个路口的实际情况,可以确定如下 13 个可能通行的线路。

A→B A→C A→D
B→A B→C B→D
D→A D→B D→C
E→A E→B E→C E→D
为了叙述方便,把 A→B 简写成 AB,并且用一个小椭圆把它框起来,在不能同时行驶的线路间画一条连线(表示它们互相冲突),便可以得到如下图所示的图1.2的模型。

图1.2
这样就把要解决的问题借助图的模型清楚而严格地表达出来,结果是把一个实际问题变成了一个图的问题,即将图中的顶点分组,使有线相连的顶点不在同一个组里。

显然,这个问题的解是不唯一的。

最容易的方法就是把每一个顶点代表的一条行驶路线都单独分为一组,一共分成 13 组,就得到这个问题的一个可行解。

为了设计一个最佳方案,得到问题的最优解,即需要得到图中顶点的最少分组数。

这样设置交通灯的问题就等价为对图的顶点染色的问题。

2.图顶点的着色问题
图顶点着色的基本思想:先用一种颜色给尽可能多的顶点上色,然后用另一种颜色在未着色顶点中给尽可能多的顶点上色,如此反复直到所有顶点都着色为止。

选用一种新颜色给顶点上色的基本操作如下。

(1)选出一个未着色的顶点,并用新颜色上色。

(2)寻找那些仍未着色的顶点,如果某顶点与新颜色着色的顶点没有边相连,则可将这个顶点用该新颜色上色。

例如,应用这种方法对图 1.2中的顶点进行着色,可以得到下面一种分组,如图 1.3 所示。

绿色: AB AC AD BA DC ED
蓝色: BC BD EA
黄色: DA DB
红色: EB EC
图1.3
实际上,根据顶点处理顺序的不同,可能得到不同的分组,但最少分组数均为 4。

假设需要着色的图是 G,集合 V 1 包括图中所有未被着色的顶点,着色开始时 V 1 是图 G 的所有顶点集合。

NEW 表示已确定可以用新颜色着色的顶点集合。

3.建立邻接矩阵的流程图
3.程序实现
(1)输入图函数 void Creat_MG(MGraph *MG)
void Creat_MG(MGraph *MG)
{
int i,j,k;
VexList L,new1,tail;
int v1,v2;
printf("请输入顶点数 : ");
scanf("%d",&MG->vexnum);
printf("\n请输入边数 : ");
scanf("%d",&MG->arcnum);
L=(VexList)malloc(sizeof(VexNode));
L->next=NULL; tail=L;
printf("\n请输入 %d 个顶点(string)\n",MG->vexnum); for(i=1;i<=MG->vexnum;++i){
new1=(VexList)malloc(sizeof(VexNode));
new1->num=i;
scanf("%s",new1->data);
new1->next=NULL;
tail->next=new1;
tail=new1;
} MG->vexs=L;
for(i=1;i<=MG->vexnum;i++){
for(j=1;j<=MG->vexnum;j++) {
MG->arcs[i][j]=0;
}
}
printf("\n请输入%d条边 v1(int) v2(int)\n",MG->arcnum); for(k=1;k<=MG->arcnum;k++){
printf("输入边 v1(int) v2(int) : ");
scanf("%d %d",&v1,&v2);
MG->arcs[v1][v2]=MG->arcs[v2][v1]=1;
}
}
(2)染色函数void colorUp(MGraph MG)
给各个顶点染色,然后输出染色结果,并调用判断颜色是否满足要求函数。

从第一个顶点开始染色,而后判断和其相邻的顶点的颜色是够与第一个顶点相同。

部分代码如下:
void colorUp(MGraph MG)
{
VexList V,NEW,p,pre,r,q;
int color=0;
int i,j;
V=MG.vexs;
while(V->next!=NULL){
NEW=(VexList)malloc(sizeof(VexNode));
NEW->next=NULL;
pre=V;
p=pre->next;
while(p){
i=p->num;
q=NEW->next;
while(q){
j=q->num;
if(MG.arcs[i][j]==1)break;
q=q->next;
}
if(q==NULL) {
pre->next=p->next;
p->next=NEW->next;
NEW->next=p;
p=pre->next;
}
else {
pre=p;
p=p->next;
}
}
(3)主程序 main()
main()
{ MGraph MG;
Creat_MG(&MG); /*调用函数建立图的邻接矩阵 */
colorUp(MG);
getch();
}
3、调试分析:
程序的编写和调试基本正常。

遇到的问题主要是:矩阵的边界问题。

根据这个五叉路口通行的具体情况,可以确定13条通行线路,由于C到E为单行线,又由于A路口可以到达B、C、D这三个路口的线路;B路口有到达A、C、D一共三条线路;D路口有到达A、B、C一共三条线路;E路口有到达A、B、C、D一共四条线路,总共得到13条路线,把这十三条当成图的节点,再根据在不能同时行驶的线路间即节点间画一条连线(表示它们互相冲突)从而建立图的模型。

由这些冲突的线路一共有20条,它们分别是从AB到BC、BD、DA、EA共四条线路;从A C到BD、DA、DB、EA、EB共五条线路;从AD到EA、EB、EC共三条线路;从BC到DB、EB共两条线路;从BD 到DA、EB、EC共三条线路;从DA到EB、EC共两条线路;从DB到
EC共一条线路,那么总计4+5+3+2+3+2+1=20 条。

而对图的这些顶点进行着色,其主要思想是先用一种颜色尽可能多给顶点着色,然后用另一种颜色在未着色的顶点中进可能多给顶点着色,如此反复进行直到所有的顶点都已上完色为止。

本实验算法是使用二维数组遍历,由于遍历第一层循环只是在遍历矩阵的第一维度,长度为n,遍历第二层循环是在遍历数组第一维度对应下标下的一维数组,长度为n,因此都要用O(n²)的时间。

4、运行结果:
(1)提示输入顶点数和边数(以本题为例,输入顶点数13,边数20)(2)提示输入顶点信息(即13条路线)
(3)提示输入边的信息,即节点位置(相冲突路线)(4)最后结果
5、实验总结:
本次实验主要为了解决实际问题而构造解决实际问题的图的模型,还有熟悉邻接矩阵和邻接表这两种存储结构的特点,这次综合实验应用了建立链表和运用邻接矩阵形式来建立图,根据具体问题的需要对顶点链表拆分成若干个子链表然后输出着色后的分组。

通过这次数据结构课程设计,使我对C语言有了比以前更进一步的认识,通过实践的学习,让我认识了邻接表和邻接矩阵的编程方法,对C语言有了更深的认识。

课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对我们的实际工作能力的具体训练和考察过程。

回顾此次课程设计,从理论到实践,可以学到很多的东西,同时不仅可以巩固了以前所学的知识,而且学到了很多在书本上所没有学到的知识。

通过这次课程设计使我们懂得了理论与实践相结合的重要性,设计过程中需要我们一边设计一边探索,这这个过程当中我发现自己在数据结构方面知识掌握不够深入,对一些基本概念不能很好的理解,对一些数据结构不能够熟练的进行上机实现,这是自己比较薄弱的。

学好基础知识是理论付
诸实践的前提,这样理论和实践才能充分地结合起来。

在以后的学习中,我还要努力改正,充分利用上机实验的机会提高自己。

五、参考文献
[1] 严蔚敏,吴伟民,《数据结构》,北京:清华大学出版社,2006年
[2]苏小红,《C语言程序设计》(第3版)2015年
六、附录
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 50 /* 最大顶点个数 */
typedef struct node
{
char data[3];
int num;
struct node*next;
}VexNode,*VexList;
typedef struct{
VexList vexs; /* 顶点信息用字符表*/
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];/* 邻接矩阵 */ int vexnum,arcnum; /* 图的顶点数和边数 */
}MGraph;
void Creat_MG(MGraph *MG)
{
// 输入顶点和边的信息 , 建立图的邻接矩阵
int i,j,k;
VexList L,new1,tail;
int v1,v2;
// 输入顶点数
printf("请输入顶点数 : ");
scanf("%d",&MG->vexnum);
// 输入边数
printf("\n请输入边数 : ");
scanf("%d",&MG->arcnum);
// 输入顶点信息 , 建立顶点链表
L=(VexList)malloc(sizeof(VexNode));
L->next=NULL; tail=L;
printf("\n请输入 %d 个顶点(string)\n",MG->vexnum); for(i=1;i<=MG->vexnum;++i)
{
new1=(VexList)malloc(sizeof(VexNode));
new1->num=i;
// printf("\n第 %d 个顶点 : ",i);
scanf("%s",new1->data);
new1->next=NULL;
tail->next=new1;
tail=new1;
}
MG->vexs=L;
// 初始化邻接矩阵
for(i=1;i<=MG->vexnum;i++)
{
for(j=1;j<=MG->vexnum;j++)
{
MG->arcs[i][j]=0;
}
}
// 输入边信息 , 建立邻接矩阵
printf("\n请输入 %d 条边 v1(int) v2(int)\n",MG->arcnum); for(k=1;k<=MG->arcnum;k++)
{
printf("输入边 v1(int) v2(int) : ");
scanf("%d %d",&v1,&v2);
MG->arcs[v1][v2]=MG->arcs[v2][v1]=1;
}
}
void colorUp(MGraph MG)
{
/* 将 MG 的顶点链表拆分成若干个子链表,每个子链表中的顶点间均无边相连 */
VexList V,NEW,p,pre,r,q;
int color=0;
int i,j;
V=MG.vexs;
while(V->next!=NULL)
{
/* 将集合 NEW 清空 */
NEW=(VexList)malloc(sizeof(VexNode));
NEW->next=NULL;
/* 将 V 拆分出一个子链表 NEW*/
pre=V;
p=pre->next;
while(p)
{
i=p->num;
q=NEW->next;
while(q)
{
j=q->num;
if(MG.arcs[i][j]==1)break;
q=q->next;
}
if(q==NULL)/* 拆分当前 p 结点到 NEW 中 */
{
pre->next=p->next;
p->next=NEW->next;
NEW->next=p;
p=pre->next;
}
else
{
pre=p;
p=p->next;
}
} /* 输出子链表 NEW*/
color++;
printf("\ncolor %d : ",color);
q=NEW->next;
while(q)
{
printf("%s ",q->data);
q=q->next;
}
}
}
main()
{ /*(1).*/MGraph MG;
/*(2).*/ Creat_MG(&MG); /*调用函数建立图的邻接矩阵 */ /*(3).*/ colorUp(MG);
/*(4).*/getch();
}。

相关文档
最新文档