算法分析与设计课程设计说明书地图着色学院:计算机与控制工程学院专业:计算机科学与技术学生姓名:xxxxx学号:成绩学生姓名:xxxxx 学号:成绩指导教师:内容提要此题为地图着色问题,由地图着色问题很容易想到图的着色问题,因此可以把地图抽象为无向图来解决地图的着色问题。
对地图的抽象相当于对图的抽象,即以邻接矩阵来实现地图的区域相邻的描绘,而对地图的区域数即以图的顶点数来描绘。
设计说明书的内容包括需求分析,概要设计,详细设计,代码实现,后期测试等内容,需求分析是对此问题所需要实现的功能的介绍,概要设计是对所需要实现功能的模块划分,以及初步的实现思想,详细设计通过编写大致的代码来实现功能,代码实现则是具体的解决问题,解决此问题设计了两个算法,贪心,回溯,在程序的测试阶段,回溯算法对同一个问题的解决速率高于贪心算法,但是结果都是以最少的颜色数来染色。
课题实现的环境是在window环境下的eclipse中,通过在其中输入地图的区域数,图的连接情况,来选择相应的算法来实现染色,本次课题所采用的数据结构主要是二维数组来抽象图的邻接矩阵。
目录1引言(或绪论) (1)2需求分析 (2)2.1 问题分析 (2)2.3问题解决 (2)2.3 运行环境及开发工具 (3)2.4功能需求 (3)2.4.1 地图的抽象及输入 (3)2.4.2 地图着色的算法设计 (3)2.4.3 界面设计 (3)2.4.4 输出设计 (3)2.5任务分配 (4)3概要设计 (4)3.1 数据定义 (4)3.2 功能模块定义 (4)3.2.1 地图的抽象输入模块 (4)3.2.2 输出模块 (4)3.2.3 地图染色模块 (4)3.2.4 界面设计模块 (5)3.2.5 主模块 (5)3.3 程序流程图 (6)4 详细设计 (7)4.1 地图输入模块 (7)4.1.1 数据类型 (7)4.1.2 具体实现 (7)4.2 界面设计模块 (7)4.2.1 数据类型 (7)4.2.2 具体实现 (7)4.3 算法设计模块 (9)4.3.1 回溯法过程 (9)4.3.2 贪心法过程 (10)5 程序设计模块 (11)5.1 界面设计代码 (11)5.2 染色实现模块 (15)6 程序测试 (19)6.1 运行结果 (19)6.2 贪心、回溯着色结果及分析 (19)7 算法时间、空间复杂度分析 (22)7.1 递归回溯 (22)7.2 贪心算法 (22)8 课设总结…………………………………………………………………………2 2 8.1 已实现功能及不足 (22)8.2 心得体会 (22)参考文献 (24)1引言(或绪论)此次课程设计的要求是已知某地图(如中国地图),对各区域进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少。
此问题就是经典的地图着色问题,地图着色问题与四色定理是紧密相关的。
地图着色问题与著名四色定理:那么可以用四种颜色来给这些区域染色,使得每两个邻接区域染的颜色都不一不会有两个邻接的区域颜色相同。
这就是著名的四色定理,由四色定理可以想到只需要四种颜色就可以为一个区域的地图着上颜色,而且相邻区域的颜色不相同。
2 需求分析2.1 问题分析:地图着色问题是一个抽象的图形学问题,用程序实现对各个区域进行着色,并且相邻省所用的颜色不同,同时保证颜色的总数最少,那么就是如何将这些抽象的进行数据化。
如何将程序所需要的功能模拟着色在计算机中编程实现。
2.2 问题解决:计算机中,图主要可以用两种方法表示:邻接矩阵和邻接链表。
N个顶点的邻接矩阵是一个N*N的布尔矩阵,图中的每一个顶点都由一行或者一列来表示,如果从第i个顶点和第j个顶点之间有边连接,则矩阵第i行,第j列的元素等于1,如果没有边连接,则等于0.这就是图的邻接矩阵表示那么地图也可以抽象为一个图,其可以用邻接矩阵来进行模拟:对于每一个地图,我们可以把每一个区〔区域或国家) 看作一个点,而区与区之间的邻接关系看作点与点之间的连线。
从而将地图抽象为一个图,然后就可以用邻接矩阵抽象。
如下图:其邻接矩阵为:A B C D EA 0 1 1 0 0B 1 0 1 1 1C 1 1 0 0 1D 0 1 0 0 1E 0 1 1 1 12.3运行环境及开发工具:运行环境:windows系统开发工具:eclipse编程工具2.4 功能需求:2.4.1:地图的抽象及输入:给定一个地图,要求画出绘制出其图的形式,并在计算机上用邻接矩阵实现。
相应的顶点为0,则表示两点邻接,否则,就不邻接,为1.2.4.2:地图着色的算法设计:回溯法:本题可采用回溯法进行着色。
当t=1时,对当前第t个顶点开始着色:若t>n,则已求得一个解,输出着色方案即可。
否则,依次对顶点t着色1-m,若t与所有其它相邻顶点无颜色冲突,则继续为下一顶点着色;否则,回溯,测试上一颜色。
回溯法的主要就是选择各种颜色,直到把此点着完色为止。
贪心法:选择一种颜色,以任意顶点作为开始顶点,依次考察图中的未被着色的每个顶点,如果一个顶点可以用颜色1着色,换言之,该顶点的邻接点都还未被着色,则用颜色1为该顶点着色,当没有顶点能以这种颜色着色时,选择颜色2和一个未被着色的顶点作为开始顶点,用第二种颜色为尽可能多的顶点着色,如果还有未着色的顶点,则选取颜色3并为尽可能多的顶点着色,依此类推,直到所有顶点都着上颜色。
贪心法就是选择一种颜色,最大化的将图中的各点都用这种颜色着上。
2.4.3:界面设计:地图着色的软件界面设计,选择何种算法,以及选择几种颜色来为相应的地图桌上颜色。
2.4.4:输出设计按要求输出动态的着色过程以及最终的染色结果,同时输出最终的着色结果,以及最少颜色数,在输出框里面输出。
2.5 任务分配:xxx:贪心法算法设计,界面设计xxx:回溯法算法设计3概要设计3.1 数据定义:int c[n+1][n+1]:邻接矩阵的中的数据只为0.1int color [n+1]:存取对对应的点的颜色,颜色用1,2,3,4表示int n:定义对应的点数int N 着色的颜色数3.2功能模块定义:3.2.1 地图的抽象输入模块:按操作者要求输入相应地图对应图的点数,以及相应点与其他点的连接情况,此输入在界面输入,其中点数表示某个区域的地区数,而连接情况表示各区域的相邻情况,用此来抽象地图。
3.2.2 输出模块:按操作者输入的数据,执行相应的算法,并且在界面上显示出来最终的结果,输出的有图的邻接矩阵,着色方案,还有图的着色的最少颜色数。
3.2.3 地图的染色模块:利用贪心算法以及回溯算法来为地图进行着色,即判断相应的点应该着那种颜色。
回溯法算法过程:设数组color[n+1]表示各顶点的着色情况,其中n表示相应的点数,回溯法:1.将数组color[n]初始化为0;2.s=1;3.while (s<=n)3.1 依次考察每一种颜色,若顶点s的着色与其他顶点的着色不发生冲突,则转步骤3.2;否则,搜索下一个颜色;3.2 若顶点已全部着色,则输出数组color[n+1],以及数组color[n+1]返回;3.3 否则,3.3.1 若顶点s是一个合法着色,则s=s+1,转步骤3处理下一个顶点;3.3.2 否则,重置顶点k的着色情况,换第二种颜色给顶点k着色,转步骤3。
主要函数:hscolor()贪心法算法过程:设数组color[n+1]表示各顶点的着色情况,算法如下:1.m=0,sum=0; //m着色的最少颜色数,sum已经着色的顶点数顶点12.while(sum<n)3.m=m+14. for (i=1; i<=n; i++)5.寻找可以着颜色1的第一个点,找到就终止此循环6.for (i=2; i<=n; i++)7.循环用颜色m为尽量多的未着色顶点着色,7.1 如果判断的点能着颜色m,则color[i]=m,sum++7.2 如果判断的点不能着此颜色,则找寻下一个能着此颜色得点8.跳回第三步,直到sum>=n5.输出color[n],已经最少的颜色数主要函数:txcolor3.2.4 界面设计模块:按题目要求在界面上输入地图的区域数,各区域的连接情况以及选择何种算法来进行着色。
结果输出在结果框。
3.2.5 主模块:利用以上设计的各个模块来进行调用,其中要选择相应的算法(回溯,贪心)来实现着色,从而完成地图着色,并且直观的结果在屏幕上显示出来。
3.3 程序流程图4 详细设计4.1 地图输入模块4.1.1数据类型:int n;顶点数int c[n+1][n+1]; 邻接矩阵String[] data;地图中各点的邻接连接情况,用0.1表示4.1.2 具体实现:n = textField.getText();//将定义的textField中的数据给nString[] data = textArea1.getText().split(" ");//将textArea1中的0.1数组给datafor (int i = 1; i < n+1; i++)for (int j = 1; j < n+1; j++)Array_1.c[i][j] = data[(i-1)*Array_1.n+j-1] //将data一维数组赋值给c二维数组4.2 界面设计模块4.2.1 数据类型public JTextField textField = new JTextField();public JTextArea textArea1 = new JTextArea();//设置文本域public Jbutton button;//设置按钮public static JTextArea textArea3 = new JTextArea();//文本域private JLabel label_1;//输入文本标签private JPanel contentPane;//整个界面4.2.2 具体实现*******************************设计主面板**************************setTitle("图的着色");//设置名字setBounds(100, 100, 604, 380); //设置大小contentPane = new JPanel();setContentPane(contentPane);contentPane.setBackground(Color.GREEN); //设置颜色*******************************设计结束*********************************************************文本域1************************** JLabel label = new JLabel("请输入地图的区域数");label.setFont(new Font("微软雅黑", Font.BOLD, 15));label.setBounds(23, 10, 166, 34);contentPane.add(label);textField.setBounds(23, 42, 192, 34);textField.setText("5");//设置初始值contentPane.add(textField);textField.setColumns(10);*******************************设计结束*********************************************************文本域2**************************label_1 = new JLabel("请输入各区域连接情况");label_1.setFont(new Font("微软雅黑", Font.BOLD, 13));label_1.setBounds(23, 86, 166, 30);contentPane.add(label_1);JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(23, 125, 192, 147);contentPane.add(scrollPane);textArea1.setText("0 1 1 0 0 1 0 1 1 1 1 1 0 0 1 0 1 0 0 1 0 1 1 1 1");//设置文本域二的初始值scrollPane.setViewportView(textArea1);*******************************设计结束*********************************************************按钮设计************************** JButton button = new JButton("贪心法");button.setFont(new Font("微软雅黑", Font.BOLD, 14));button.setBounds(23, 282, 92, 34);button.addActionListener(new MyEvent());contentPane.add(button);JButton button = new JButton("回溯法");//设置按钮名字button.addActionListener(new MyEvent());button.setFont(new Font("微软雅黑", Font.BOLD, 14));button.setBounds(140, 282, 92, 34);contentPane.add(button);*******************************设计结束*********************************************************结果文本域************************** JLabel label = new JLabel("染色结果");label.setFont(new Font("微软雅黑", Font.BOLD, 15));label.setBounds(369, 20, 84, 15);contentPane.add(label);JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(248, 42, 321, 273);contentPane.add(scrollPane);scrollPane.setViewportView(textArea3);*******************************设计结束************************** 4.3 算法设计模块4.3.1 回溯法主要代码int i;int N=4;//设计颜色数为4,但是并不是用这么多颜色,程序最终的结果是最优的,即输出来的颜色数肯定最少,因为四色定理 if(s>n)//递归出口,递归的最终出口{output();//输出结果}else{for(i=1;i<=N;i++)//对每一种色彩逐个测试{color[s]=i;if(colorsame(s)==0){//当测试这个颜色i=1为某个点着色不合格时,用第二种颜色着色,i=2进行判断,合格进行递归调用,不合格就使用第三种颜色,即i=3trycolor(s+1);//进行下一块的着色break;//停止回溯,因为已经着色成功}}}4.3.2 贪心法主要代码while(sum< n){//最终的判定条件,即将所有点着色完毕 m++;//第一次循环,m=1,m即为颜色数for(int i=1;i<=n;i++){//此循环用来查找第一个为着色的并且可以着色m的点if(color[i]==0){j=i;//j=1color[j]=m;sum++;break;//结束当前循环}}for(int i=j+1;i<=n;i++){//i=2if(color[i]!=0) continue;//color[i]的起始值为零,false,不执行continue,表示没有着色,因此执行下一步,否则起始值不为0,则表示已经成功着上颜色。