当前位置:文档之家› 图着色

图着色

算法设计课程设计题目图着色问题姓名学号专业年级指导教师职称2014年 12月 4日图的m着色问题1 摘要 (3)2 图的着色问题 (4)2.1 图的着色问题的来源 (4)2.2 图的着色问题的描述 (4)3算法的基本思想 (4)3.1 求极小覆盖法----布尔代数法 (4)3.2 穷举法-Welch Powell着色法 (4)3.3 回溯法 (4)3.4 贪心法 (4)3.5 蚁群算法 (5)4算法步骤 (5)4.1 求极小覆盖法----布尔代数法 (4)4.2 穷举法-Welch Powell着色法 (4)4.3 回溯法 (4)4.4 贪心法 (4)4.5 蚁群法 (4)5 理论分析(复杂度比较)、实验性能比较 (7)5.1 复杂度分析 (4)5.2 实验性能比较 (4)6 心得体会 (8)7参考文献 (8)8 附录 (8)摘要图论是近年来发展迅速而又应用广泛的一门新兴学科,已广泛应用于运筹学、网络理论、信息论、控制论、博奕论以及计算机科学等各个领域。

一般说来,图的着色问题最早起源于著名的“四色问题”,染色问题不但有着重要的理论价值,而且,它和很多实际问题有着密切联系,例如通讯系统的频道分配问题,更有着广泛的应用背景. 本文首先讨论了人工智能的状态搜索方法在图着色中的具体应用,并用可视化方法展示了低维的着色空间和约束的具体意义。

关键词:图着色 c++代码2、图的着色问题2.1图的着色问题的来源1852年,毕业于伦敦大学的弗南西斯·格思里(Francis Guthrie)在一家科研单位从事地图着色工作时,发现“任何一张地图似乎只用四种颜色就能使具有共同边界的国家着上不同的颜色。

”用数学语言来表示,即“将平面任意地细分为不相重迭的区域,每一个区域总可以用1,2,3,4这四个数字之一来标记,而不会使相邻的两个区域得到相同的数字。

”这就是源于地图着色的四色猜想问题。

这里所指的相邻区域,是指有一整段边界是公共边界。

如果两个区域只相遇于一点或有限多点,就不叫相邻。

因为用相同的颜色给它们着色不会引起混淆。

用四种颜色着色的世界地图:采用四种颜色着色的美国地图:2.2图的着色问题的描述(一)图的着色问题是由地图的着色问题引申而来的:用m种颜色为地图着色,使得地图上的每一个区域着一种颜色,且相邻区域颜色不同。

(二)通常所说的着色问题是指下述两类问题:1.给定无环图G=(V,E),用m种颜色为图中的每条边着色,要求每条边着一种颜色,并使相邻两条边有着不同的颜色,这个问题称为图的边着色问题。

2.给定无向图G=(V,E),用m种颜色为图中的每个顶点着色,要求每个顶点着一种颜色,并使相邻两顶点之间有着不同的颜色,这个问题称为图的顶着色问题。

(三)问题处理:如果把每一个区域收缩为一个顶点,把相邻两个区域用一条边相连接,就可以把一个区域图抽象为一个平面图。

例如,图12-1(a)所示的区域图可抽象为12-1(b)所表示的平面图。

19世纪50年代,英国学者提出了任何地图都可以4中颜色来着色的4色猜想问题。

过了100多年,这个问题才由美国学者在计算机上予以证明,这就是著名的四色定理。

例如,在图12-1中,区域用城市名表示,颜色用数字表示,则图中表示了不同区域的不同着色问题。

(在本文中主要讨论顶点着色)3、算法的基本思想目前求图着色问题主要有以下几种方法3.1求极小覆盖法----布尔代数法采用代数的方法来解决顶点着色问题3.2穷举法-Welch Powell着色法采用穷举一切的方法来找出所有的解3.3回溯法回溯法的基本思想是,在确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。

这个开始结点就成为一个活结点,同时也成为当前的扩展结点。

在当前的扩展结点处,搜索向纵深方向移至一个新结点。

这个新结点就成为一个新的活结点,并成为当前扩展结点。

如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。

换句话说,这个结点不再是一个活结点。

此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。

回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。

3.4贪心法贪心算法:贪心策略:选择一种颜色,以任意顶点作为开始顶点,依次考察图中的未被着色的每个顶点,如果一个顶点可以用颜色1着色,换言之,该顶点的邻接点都还未被着色,则用颜色1为该顶点着色,当没有顶点能以这种颜色着色时,选择颜色2和一个未被着色的顶点作为开始顶点,用第二种颜色为尽可能多的顶点着色,如果还有未着色的顶点,则选取颜色3并为尽可能多的顶点着色,依此类推。

3.5蚁群算法4、算法步骤4.1 求极小覆盖法----布尔代数法例1:求图12-2G的顶色数解:Step1:求极大独立集先求图G的极小覆盖,(a+bd)(b+aceg)(c+bdef)(d+aceg)(e+bcdf)(f+ceg)(g+bdf)化简得aceg+bcdeg+bdef+bcdf故G的极小覆盖为{a,c,e,g},{b,c,d,e,g},{b,d,e,f},{b,c,d,f},{b,d,f},{a,f},{a,c,g},{a,e,g}取其补集,得到G的所有极大独立集:Step2:求出一切若干极大独立集和所有顶点的子集显然我们可以选用4种颜色给每个顶点涂色,或者选用3种颜色分别给3个极大独立集涂色,例如为{b,d,f}中的b、d、f涂颜色1,为{a,f}中的a涂颜色2,为{a,c,g} 中的c和g涂颜色3,为{a,e,g}中的e涂颜色4。

Step3:从中挑选所用极大独立集个数最小者,即为X(G)但上述子集的颜色数都不是X(G),正确的应该是X(G)=3,该子集为:给{b,d,f}中的b,d,f涂颜色1,为{a,e,g}中a,e,g涂颜色2为{a,c,g}中的c涂颜色3。

由此可见,求色数其需要求极大独立集以及一切若干极大独立集的和含所有顶点的子集,对于大图,因为图计算量过大而成为实际上难以凑效的算法,所以不是一个好算法,一般我们采用贪心法等近似算法来求解。

4.2 穷举法-Welch Powell着色法穷举法:I.将图G中的结点按度数的递减顺序进行排列(这种排列可能不是唯一的,因为有些结点的度数相同)。

II.用第一种颜色对第一结点着色,并按排列顺序对与前面着色结点不邻接的每一结点着上同样的颜色。

III.用第二种颜色对尚未着色的结点重复II,用第三种颜色继续这种做法,直到所有的结点全部着上色为止。

4.3 回溯法回溯法:设数组color[n]表示顶点的着色情况,回溯法求解m着色问题的算法如下:图着色回溯法:1.将数组color[n]初始化为0;2.k=1;3.while (k>=1)3.1 依次考察每一种颜色,若顶点k的着色与其他顶点的着色不发生冲突,则转步骤 3.2;否则,搜索下一个颜色;3.2 若顶点已全部着色,则输出数组color[n],返回;3.3 否则,3.3.1 若顶点k是一个合法着色,则k=k+1,转步骤3处理下一个顶点;3.3.2 否则,重置顶点k的着色情况,k=k-1,转步骤34.4 贪心法算法步骤:设数组color[n]表示顶点的着色情况,贪心法求解图着色问题的算法如下:图着色贪心法:1.color[1]=1; //顶点1着颜色12.for (i=2; i<=n; i++) //其他所有顶点置未着色状态color[i]=0;3.k=0;4.循环直到所有顶点均着色4.1 k++; //取下一个颜色4.2 for (i=2; i<=n; i++) //用颜色k为尽量多的顶点着色4.2.1 若顶点i已着色,则转步骤4.2,考虑下一个顶点;4.2.2 若图中与顶点i邻接的顶点着色与顶点i着颜色k不冲突,则color[i]=k;5.输出k;4.5 蚁群法蚁群算法:ai:表示第i只蚂蚁的起始城市;pmax:蚂蚁i下一步所选城市中最大的概率。

建立邻接矩阵Y为n×n的矩阵,表示地区与地区之间的邻接关系,Yic表示城市i与城市c的邻接关系,当城市i与城市c是同一个城市用Yic=0表示,当城市i与城市c不相邻,Yic取一较小值(如Yic=-1);当城市i与城市c相邻Yic取一较大值(如Yic=1)。

ai与c城市的表更新方程:ai到c城市的概率计算公式:算法:For t←1将k只蚂蚁随机置于k个顶点上将k只蚂蚁出发点置于当前解集中For m←1 to n/kFor i←1 to kFor c←1 to n按概率pkic选择顶点c移动蚂蚁i到顶点c将顶点c置于蚂蚁i的当前解集检查着色条件End forEnd for检查若未完成的任务End fort←t+1Δτic←0End for 输出满意h5、理论分析(复杂度比较)、实验性能比较5.1复杂度分析当图的顶点数为20时计算时间与最小色数:算法 | 复杂度 | 色数 |极小覆盖 | O(n^2) | 4 |穷举法 | O(n^2) | 4 |回溯法 | O(n^2) | 4 |贪心算法 | O(n^2) | 4 |蚁群法 | O(n^2) | 4 |5.2性能比较布尔代数的性能是最高的但是用算法实现起来较为困难,而且不能得到最优解,得不到全部的解。

穷举法的性能是最低的,它穷举了所有的方法,可以找出所有的方法。

回溯法和贪心算法的性能相似。

蚁群算法的实现较为困难,有随机性。

布尔代数 >贪心算法 >回溯法 >蚁群法 >穷举法6、心得体会这次我们小组选了地图着色这个题目,最开始我们都不了解什么是地图着色,后来通过在网上查找了大量资料才明白地图着色是基于历史上著名的四色问题。

图着色问题对于现实生活中也有许多的应用,比如交通管理系统、安排考试、贮藏问题等,以前觉得算法与现实生活离得比较远,有时候也会产生对算法的厌恶情绪,但是通过对它的学习才知道现实生活中很多地方都用到了算法。

以前读浪潮之巅时有一章就是讲网络搜索的,那个就采用了布尔代数,好的算法算法很大程度上可以提高效率,节约时间,这在计算机网络方面很明显。

此外通过小组一起的学习,我们学会了小组合作的重要性,大家一起分工合作,每个人研究一个算法,然后大家一起讨论,这样问题就很快得到了解决。

7、附录算法采用c++来实现,而且图采用了矩阵来存储,图的存储可以采用矩阵和链表两种方式,链表方式存储起来比较节约空间。

链表存储有顺序存储与链式存储两种方式,在查找时不易,故此文中的代码都采用了矩阵来存储。

由于布尔代数与蚂蚁算法用算法不易实现,故附录中只附上了其他的两种算法。

8、参考文献[1] Kyle Loudon.算法精解.机械工业出版社.2012.9.1[2]谭浩强.C++面向对象程序设计[M].北京.清华大学出版社,2006.[3]王晓东.计算机算法设计与分析(第3版)[M].北京.电子工业出版社.2007.[4]Cliff A.Shaffer.数据结构与算法分析(C++版).2013年第三版[5]朱洪.算法设计和分析[M].上海科学技术文献出版社,1989,162-163.附录1贪心算法代码#include <stdio.h>#define N 21int ok(int metro[N][N],int r_color[N],int current){/*测试当前着色方案是否可行*/int j;for(j=1;j<current;j++)if(metro[current][j]==1&&r_color[j]==r_color[current])return 0;/*城市相邻且颜色相同*/return 1;}void go(int metro[N][N],int r_color[N],int sum,int current){int i;if(current<=sum)/*检查所有城市*/for(i=1;i<=4;i++)/*测试每种颜色*/{r_color[current]=i;/*尝试着色*/if(ok(metro,r_color,current))/*若尝试成功*/{go(metro,r_color,sum,current+1);/*检查下一个城市*/return;}}}void main(){int r_color[N]={0};int i;int metro[N][N]={{0},/*邻接矩阵*/{0,1,1,1,1,1,1},{0,1,1,1,1},{0,1,1,1,0,0,1},{0,1,1,0,1,1},{0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0,1},{0,1,0,1,0,1,1,1,1,1},{0,0,0,0,0,0,1,1,1},{0,0,0,0,0,0,1,1,1,1,0,0,1},{0,0,0,0,0,1,1,0,1,1,0,0,1,1,1,0,1},{0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,1},{0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1},{0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,1,1},{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0,1},{0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},{0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1}};go(metro,r_color,20,1);printf("\n");for(i=1;i<=20;i++)/*输出着色方案*/printf("%3d",r_color[i]);printf("\n");}1.1结果截图2回溯法代码#include<stdio.h>int color[100];bool ok(int k,int c[][100]) //判断顶点k的着色是否发生冲突{int i,j;for(i=1;i<k;i++){if(c[k][i]==1&&color[i]==color[k])return false;}return true;}void graphcolor(int n,int m,int c[][100]){int i,k;for(i=1;i<=n;i++)color[i]=0;k=1;while(k>=1){color[k]=color[k]+1;while(color[k]<=m)if(ok(k,c)) break;else color[k]=color[k]+1; //搜索下一个颜色if(color[k]<=m&&k==n){for(i=1;i<=n;i++)printf("%d ",color[i]);printf("\n");}else if(color[k]<=m&&k<n)k=k+1; //处理下一个顶点else{color[k]=0;k=k-1;//回溯}}}void main(){int i,j,n,m;int c[100][100];//存储n个顶点的无向图的数组printf("输入顶点数n和着色数m:\n");scanf("%d %d",&n,&m);printf("输入无向图的邻接矩阵: \n");for(i=1;i<=n;i++)for(j=1;j<=n;j++)scanf("%d",&c[i][j]);printf("着色所有可能的解:\n");graphcolor(n,m,c);}2.1结果截图。

相关主题