软件综合课程设计无向图着色.docx
《软件综合课程设计无向图着色.docx》由会员分享,可在线阅读,更多相关《软件综合课程设计无向图着色.docx(28页珍藏版)》请在冰豆网上搜索。
软件综合课程设计无向图着色
沈阳航空航天大学
课程设计报告
课程设计名称:
软件综合课程设计
课程设计题目:
连通图的着色问题
院(系):
计算机学院
专业:
计算机科学与技术
班级:
学号:
姓名:
指导教师:
说明:
结论(优秀、良好、中等、及格、不及格)作为相关教环节考核必要依据;格式不符合要求;数据不实,不予通过。
报告和电子数据必须作为实验现象重复的关键依据。
学术诚信声明
本人声明:
所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。
尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。
与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。
报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。
本人签名:
日期:
2017年月日
课程设计任务书
课程设计名称
软件综合课程设计
专业
计算机科学与技术
学生姓名
班级
学号
题目名称
连通图着色问题
起止日期
2016
年
12
月
19
日起至
2017
年
1
月
13
日止
课设内容和要求:
输入一个连通无向图到适当的存储结构中,图的结点数由键盘输入,给图上的每一个结点标记一种颜色,在保证任何相邻结点颜色不同的前提下,求解出该无向连通图所需要的最少颜色数,并给出每个结点的具体颜色,输出连通图着色动态演示过程。
设计要求:
1.系统采用可视化编程实现;
2.利用所学知识,设计相应的数据结构;
3.开发工具选择面向对象的C++等;
4.界面友好,操作方便;
5.按照课程设计规范书写课程设计报告
参考资料:
面向对象的程序设计方法语言及数据结构和离散数学相关资料
教研室审核意见:
教研室主任签字:
指导教师(签名)
年
月
日
学生(签名)
2016
年
12
月
18
日
课程设计总结:
这次的课程设计让我学到了很多东西,也复习了许多知识,
在专业知识方面:
复习了离散数学中关于图的着色算法,这次课设采用的是鲍威尔算法;由于刚开始是用C++写的,所以顺带复习了一下C++编程,前期基本功能都已经实现了。
由于课设要求界面,恰好这个学期学了JAVA,所以后期把代码转换成JAVA。
在其他方面:
更加娴熟的利用网络进行答疑解惑,参考和吸取自己有用的东西。
比如说刚开始不会做界面,回去复习和研究了老师上课课件的例子,试着编写,不懂就XX,总能找到答案。
还有就是,刚开始不会用键盘输入数据,不会画圆,不会连线,不会改变字体颜色等,这些都是从网上XX学会的。
最后,在功能一步步实现的时候,心中涌现的是一种喜悦,也许这就是程序员的乐趣所在吧。
下个学期还有毕设,通过这个课设让我更加熟练的使用Eclipse,为下个学期的毕设做准备。
指导教师评语:
指导教师(签字):
年月日
课程设计成绩
目录
1题目的内容与要求5
1.1题目的内容5
1.2题目的要求5
1.3题目理解与程序解读5
2总体设计7
2.1程序框架设计7
2.2程序数据结构设计7
3详细设计9
3.1主程序流程图9
3.2子函数流程图10
3.2.1构造函数Graph(intvexnum,intatcnum)10
3.2.2邻接表函数int_Xlist()10
3.3.3度数排序子函数int_Dushu()11
3.3.4结点着色子函数Brust_color()12
3.3.5画板画图子函数Paint()13
4调试分析15
4.1运行说明15
4.1测试用例115
4.2测试用例216
参考文献18
源程序(清单)19
1题目的内容与要求
1.1题目的内容
输入一个无向图到适当的存储结构中,给图上的每一个结点标记一种颜色,在保证任何相邻结点颜色不同的同时,求解出该图所需要的最少颜色数,并给出每个结点的具体颜色。
1.2题目的要求
1.系统采用可视化编程实现;
2.利用所学知识,设计相应的数据结构;
3.开发工具选择面向对象的C++等;
4.界面友好,操作方便;
5.按照课程设计规范书写课程设计报告
1.3题目理解与程序解读
本次课设与离散数学当中图的部分有密切的联系,连通图的着色问题,涉及到图的连通性和图的着色问题。
当图的结点之间存在通路,则此图是连通的,在此基础之上对他进行着色。
重要之处在于每个进店标记一种颜色,但要求的是相邻的结点要着上不同的颜色,要求所使用的颜色数最少即是所要求的。
解决此题的算法是韦尔奇.鲍威尔的着色理论,算法如下:
(1)将图的结点按照度数的递减顺序进行排列,(这种排列可能不是唯一的,因为有些点有相同的度数)。
(2)用第一种颜色对第一个结点进行着色,并且按排列次序,对于前面着色点不相邻的每一个结点着上同样的颜色。
(3)用第二种颜色对尚未着色的点重复第二个步骤,用第三种颜色继续这种做法,直到所有的点全部着上色为止。
所以源程序就是对韦尔奇鲍威尔算法演示。
首先输入结点个数和边的个数,结点结构体内包含结点编号,度数,结点的颜色和状态。
边的结构体当中包含结点结构体变量,用来指示边起始节点和终止结点,同时还包含边的编号。
对输入的图用关联矩阵来表示,对着色的颜色用整型的数字来表示,所以我们规定数字1—5分别表示为绿色,蓝色,黄色,红色和黑色。
初始化颜色为绿色,即是为数字1.
2总体设计
2.1程序框架设计
这个课程设计用java编写的,用一个图类,成员方法包括图的邻接矩阵建立,度数排序,结点着色函数和画板画图函数具体设计如下流程图2.1
图2.1程序框架流程图
2.2程序数据结构设计
1.定义一个图类,成员变量包括:
结点数vexnum,边数actnum;用二维数组当作邻接矩阵xlist[][];保存各点度数的数组Dushu[];标记各点是否着色的变量flag[];m1[]是用来保存各点度数递减的下标;color[]用来保存第i点应该着第color[i]种色;width1和height1为界面的大小。
具体代码如下:
publicstaticintvexnum;///////点和边
publicstaticintatcnum;
publicstaticintxlist[][]=newint[50][50];///////邻接表
publicstaticintDushu[]=newint[50];//度数
publicintflag[]=newint[50];////////////着色标记,
publicstaticintm1[]=newint[50];///////////////度数递减的下标排序
publicstaticintcolor[]=newint[50];
publicintwidth1=1000,height1=1000;
2.图类的成员方法包括:
(1)图类的构造函数,主要是初始化要输入的图的结点数和边数。
publicGraph(intvexnum1,intatcnum1)//
(2)初始化邻接矩阵,通过输入某条边的两个点来初始化邻接矩阵。
publicint[][]int_xlist()
(3)各结点度数排序,读出个点度数,把度数递减排序,在对应把度数所对应的结点号输出。
publicint[]int_Dushu()
(4)结点着色函数,从度数最大的点和不与该点相连的点开始同一种着色。
publicint[]Brust_Color()
(5)画板画出输入的图并着色。
publicvoidpaint(Graphicsg)
3详细设计
3.1主程序流程图
图3..1主函数
主函数里分别执行了构造函数,邻接表的建立函数,度数排序函数,着色函数,和画板画图函数。
首先根据提示输入结点数和边数,然后在输入边的关系,分别以各个边的起点,终点的方式输入,回车控制框内计算出输入图的邻接矩阵,各个结点的度数排序以及各个点的着色情况。
具体流程如上流程图3.1
3.2子函数流程图
3.2.1构造函数Graph(intvexnum,intatcnum)
此部分为图的信息的初始化,接收输入图的结点数和边数以及框架模式,画板的大小,背景颜色。
为后面的工作做准备。
具体流程如下流程图3.2
图3.2构造函数
3.2.2邻接表函数int_Xlist()
此部分是建立邻接矩阵。
首先初始化邻接矩阵xlist[][]=0,然后通过从输入框输入的边的关系存于临时数组,其中vex_vex[i][0]是起点,vex_vex[i][1]是终点。
然后,在把邻接矩阵中第i行的各个元素xlist[vex_vex[i][0]][vex_vex[i][1]]设置为1。
最后在控制台输出邻接矩阵。
具体流程如下流程图3.3
图3.3邻接表函数
3.3.3度数排序子函数int_Dushu()
此部分是将各个结点的度数按递减的顺序进行排列。
首先用2个循环吧各个结点的度数统计出来,然后存于Dushu[i]数组中对应的i就是i点的度数。
把Dushu[]数组赋值给temp[],在对temp[]使用冒泡排序,得到度数递减序列。
再把各个结点和度数想对应,就能得到度数递减的结点号保存在数组m1[]中,最后并输出这个序列以及该点对应的度数。
具体流程如下流程图3.4。
图3.4度数排序函数
3.3.4结点着色子函数Brust_color()
此部分是本程序中最重要的部分,即为结点进行着色。
首先初始化一些变量如统计颜色数q=1,变量k=0。
结点i应该着第color[i]种颜色。
由于m1[]保存的是度数递减的结点号排序,给i=m[k]赋值,首先判断i结点是否着色即判断flag==0。
不等则说明未着色。
然后标记第q种颜色,即color[i]=q,同时标记第flag[i]=0说明已经着色。
在读邻接矩阵,判断与点i不相连的结点j着色第q种颜色,即color[j]=q,同时标记第flag[j]=0说明已经着色。
如此循环直到最后一个点说明全部点已着色。
具体流程如下图3.5
图3.5结点着色函数
3.3.5画板画图子函数Paint()
该部分为最后在画板是画出所输入的图的函数。
首先通过循环生成总共vexnum个二维坐标,为后面画圆和连线做准备。
由着色函数得出i结点应该着第color[i]种颜色,用一个循环遍历所有结点,并分别用对应第color[i]种颜色进行画圆,再读邻接矩阵,再把与点i不相连的结点j用相同颜色画笔画出圆,同时标记第flag[j]=0说明已经着色。
最后连接结点i和结点j
如此循环直到最后一个点说明全部点已着色。
具体流程如下图3.5
图3.6画板画图函数
4调试分析
4.1运行说明
1本程序的运行环境为Eclipse;
2进入演示程序后即显示提示信息:
输入结点数:
m;
输入边数:
n;
输入第0条边:
起点:
终点:
输入第1条边:
起点:
终点:
………
………
输入第n-1条边:
输入完毕后即显示出邻接矩阵,以及度数排列顺序,给点的着色以及有几种颜色。
4.1测试用例1
输入下图所对应的信息:
4个结点,4条边,
第0条边起点:
0终点1;
第1条边起点:
0终点2;
第2条边起点:
0终点3;
第3条边起点:
1终点2;
然后就会在控制框计算出该图所对应的邻接表,各点度数,和各点度数降序排序,以及各个顶点应该着色情况,结果如下图4.1和4.2:
与此同时弹出画板,画板画出该图以及各点的着色情况。
图4.1图4.2
程序结果为至少要3颜色,同样在图4.2中也可以看出着色结果
4.2测试用例2
输入一个完全图图所对应的信息:
5个结点,10条边,
第1条边起点:
0,终点1。
第2条边起点:
0,终点2。
第3条边起点:
0,终点3。
第4条边起点:
0,终点4。
第5条边起点:
1,终点2。
第6条边起点:
1,终点3。
第7条边起点:
1,终点4。
第8条边起点:
2,终点3。
第9条边起点:
2,终点4。
第10条边起点:
3,终点4。
然后就会在控制框计算出该图所对应的邻接表,各点度数,和各点度数降序排序,以及各个顶点应该着色情况,结果如下图4.3和图4.4:
与此同时弹出画板,画板画出该图以及各点的着色情况。
图4.3图4.4
程序结果为要用5颜色,同样在图4.4中也可以看出着色结果
参考文献
[1]严蔚敏,吴伟民.《数据结构》(C语言版)[M].北京:
清华大学出版,2007年
[2]朱站立,张选平.《数据结构》[M].西安:
西安交通大学出版社,2007年
[3]左孝凌,刘永才.《离散数学》[M].上海科学技术文献出版社,1982年
源程序(清单)
importjava.util.Scanner;
importjava.applet.Applet;
importjava.awt.BasicStroke;
importjava.awt.Color;
importjava.awt.FlowLayout;
importjava.awt.Font;
importjava.awt.Frame;
importjava.awt.Graphics;
importjava.awt.Graphics2D;
importjava.awt.Stroke;
importjava.awt.event.ComponentEvent;
//importjava.awt.event.ComponentListener;
importjava.awt.event.ItemEvent;
//importjava.awt.event.ItemListener;
importjava.awt.event.WindowEvent;
importjava.awt.event.WindowListener;
importjava.util.Random;
publicclassGraphextendsFrameimplementsWindowListener{
publicstaticintvexnum;///////点和边
publicstaticintatcnum;
publicstaticintxlist[][]=newint[50][50];///////邻接表
publicstaticintDushu[]=newint[50];//度数
publicintflag[]=newint[50];////////////着色标记,
publicstaticintm1[]=newint[50];///////////////度数递减的下标排序
publicstaticintcolor[]=newint[50];
publicintwidth1=800,height1=600;
publicGraph(intvexnum1,intatcnum1)
{
this.setTitle("Graph");
this.setSize(width1,height1);
this.setBackground(Color.white);
this.setLayout(newFlowLayout());
addWindowListener(this);
vexnum=vexnum1;
atcnum=atcnum1;
}
publicint[][]int_xlist()//////需要返回一下邻接矩阵
{
Scannerin=newScanner(System.in);
inti=0,j=0;
intk,l;
intvex_vex[][]=newint[20][2];
for(i=0;i{
System.out.println("请输入第"+i+"条边的联系:
");
System.out.println("请输入起点:
");
vex_vex[i][0]=in.nextInt();
System.out.println("请输入终点:
");
vex_vex[i][1]=in.nextInt();
}
for(i=0;i<50;i++)
for(j=0;j<50;j++)
{
xlist[i][j]=0;/////////////////////初始
flag[i]=1;
}
for(i=0;i{
xlist[vex_vex[i][0]][vex_vex[i][1]]=1;////////////////构造邻接矩阵
xlist[vex_vex[i][1]][vex_vex[i][0]]=1;////////////////构造邻接矩阵?
}
System.out.println("邻接矩阵");////////////输入数据
for(i=0;iSystem.out.println(xlist[i][0]+""+xlist[i][1]+""+xlist[i][2]/*);*/+""+xlist[i][3]);////////////输入数据
System.out.println("\n");
returnxlist;////////////输入数据
}
publicint[]int_Dushu()/////需要返回度数排序、、
{
inti,j,k;
inttemp[]=newint[50];
for(i=0;ifor(j=0;j{if((xlist[i][j]==1)&&(i!
=j))
Dushu[j]++;//度数存于Dushu[]中
}
for(i=0;itemp[i]=Dushu[i];
/////////////////////////冒泡排序
for(i=0;ifor(j=0;j{if(temp[j]{k=temp[j];temp[j]=temp[j+1];temp[j+1]=k;}
}
///////////////////////////////////////
for(i=0;ifor(j=0;j{
if((flag[j]!
=0)&&(temp[i]==Dushu[j]))
{
m1[i]=j;///////度数递减的节点的下标
flag[j]=0;
break;
}
}
for(i=0;i{
System.out.println("第v"+m1[i]+"个结点的度数:
"+Dushu[m1[i]]);
}
returnm1;/////度数递减的下标排序
}
///////////////////////////////////////
publicint[]Brust_Color()//////////////////需要返回个点着色情况
{
inti=0,j=0,p=0,k=0,q=1;
for(i=0;i{flag[i]=1;color[i]=0;}
System.out.println("\n");////////////输入数据
for(;p{
i=m1[k];
if(flag[i]!
=0)
{
System.out.println("顶点"+i+"应该着第"+q+"种颜色");
flag[i]=0;
color[i]=q;
for(j=0;j{
if((j!
=i)&&(xlist[i][j]==0)&&(flag[j]!
=0))
{
System.out.println("顶点"+j+"应该着第"+q+"种颜色");
flag[j]=0;
color[j]=q;
}
}
}
else
{
k++;
continue;
}
q++;
k++;
}
intmax=color[0];
for(i=1;iif(max<=color[i])
max=color[i];
System.out.println("最少需要"+max+"种颜色");
returncolor;
}
///////////////////////////////
publicvoidpaint(Graphicsg)
{
Strokestroke1=newBasicStroke(8.0f);//设置线宽为5.0
Strokestroke2=newBasicStroke(2.0f);//设置线宽为3.0
Colorcolor0=newColor(255,0,0);//紫色
Colorcolor1=newColor(255,255,0);
Colorcolor2=newColor(0,150,100);
Colorcolor3=newColor(255,100,255);
Colorcolor4=newColor(100,255,100);/////用swith()区分各种颜色
String[]string={"0","1","2","3","4","5","6","7","8","9"};
inti=0,j=0;
intx[]=newint[10];
inty[]=newint[10];