地图着色问题

合集下载

四色问题又称四色猜想,是世界近代三大数学难题之一

四色问题又称四色猜想,是世界近代三大数学难题之一

四色问题又称四色猜想,是世界近代三大数学难题之一。

四色问题的内容是:“任何一张地图只用四种颜色就能使具有共同边界的国家着上不同的颜色。

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

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

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

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

四色猜想的提出来自英国。

1852年,毕业于伦敦大学的弗南西斯·格思里来到一家科研单位搞地图着色工作时,发现了一种有趣的现象:“看来,每幅地图都可以用四种颜色着色,使得有共同边界的国家都被着上不同的颜色。

”这个现象能不能从数学上加以严格证明呢?他和在大学读书的弟弟格里斯决心试一试。

兄弟二人为证明这一问题而使用的稿纸已经堆了一大叠,可是研究工作没有进展。

1852年10月23日,他的弟弟就这个问题的证明请教了他的老师、著名数学家德·摩尔根,摩尔根也没有能找到解决这个问题的途径,于是写信向自己的好友、著名数学家汉密尔顿爵士请教。

汉密尔顿接到摩尔根的信后,对四色问题进行论证。

但直到1865年汉密尔顿逝世为止,问题也没有能够解决。

1872年,英国当时最著名的数学家凯利正式向伦敦数学学会提出了这个问题,于是四色猜想成了世界数学界关注的问题。

世界上许多一流的数学家都纷纷参加了四色猜想的大会战。

1878~1880年两年间,著名的律师兼数学家肯普和泰勒两人分别提交了证明四色猜想的论文,宣布证明了四色定理,大家都认为四色猜想从此也就解决了。

肯普的证明是这样的:首先指出如果没有一个国家包围其他国家,或没有三个以上的国家相遇于一点,这种地图就说是“正规的”(左图)。

如为正规地图,否则为非正规地图(右图)。

一张地图往往是由正规地图和非正规地图联系在一起,但非正规地图所需颜色种数一般不超过正规地图所需的颜色,如果有一张需要五种颜色的地图,那就是指它的正规地图是五色的,要证明四色猜想成立,只要证明不存在一张正规五色地图就足够了。

地图着色问题实验报告

地图着色问题实验报告

算法设计与分析课程设计题目:地图着色问题文档:物联网工程学院物联网工程专业学号学生姓名班级二〇一三年十二月一、问题描述:地图着色问题设计要求:已知中国地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少.二、概要设计(流程图)步骤:1.已知中国地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少;2.将各省进行编号,然后利用无向图的顶点之间的边来表示各省的相邻关系;3.将各编号进行逐一着色,利用循环语句遍历各省,判断语句判断是否符合要求;4.演示程序,以用户和计算机的对话方式进行;5.最后对结果做出简单分析及总结。

流程图三、源程序#include <stdio.h>#include <stdlib.h>#define MAXedg 100#define MAX 0#define N 4 /*着色的颜色数*/int color[30]={0};/*来存储对应块的对应颜色*/ typedef char vextype;typedef int adjtype;typedef struct /*定义图*/{vextype vexs[MAXedg]; /*存放边的矩阵*/adjtype arcs[MAXedg][MAXedg]; /*图的邻接矩阵*/ int vnum,arcnum; /*图的顶点数和边数*/}Graph;int LocateVex(Graph G,char u){int i;for(i=1;i<=G.vnum;i++){if(u==G.vexs[i])return i;}if(i==G.vnum){printf("Error u!\n");exit(1);}return 0;}void CreateGraph(Graph &G) /*输入图*/{int i,j,k, w;vextype v1,v2;printf("输入图的顶点数和边数:\n");scanf("%d%d",&G.vnum,&G.arcnum);getchar();printf("输入图的各顶点:\n");for(i=1;i<=G.vnum;i++){scanf("%c",&G.vexs[i]);getchar();}for(i=0;i<=G.vnum;i++)for(j=0;j<=G.vnum;j++)G.arcs[i][j]=MAX;printf("输入边的两个顶点和权值(均用1表示):\n"); for(k=0;k<G.arcnum;k++){scanf("%c", &v1);getchar();scanf("%c", &v2);getchar();scanf("%d", &w); getchar();i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcs[i][j]=w;G.arcs[j][i]=w;}void PrintGraph(Graph G) /*输出图的信息*/{int i,j;printf("图的各顶点:\n");for(i=1;i<=G.vnum;i++)printf("%c ",G.vexs[i]);printf("\n");printf("图的邻接矩阵:\n");for(i=1;i<=G.vnum;i++){for(j=1;j<=G.vnum;j++)printf("%d ",G.arcs[i][j]);printf("\n");}}int colorsame(int s,Graph G)/*判断这个颜色能不能满足要求*/ {int i,flag=0;for(i=1;i<=s-1;i++)/*分别与前面已经着色的几块比较*/if(G.arcs[i][s]==1&&color[i]==color[s]){flag=1;break;}return flag;}void output(Graph G)/*输出函数*/int i;for(i=1;i<=G.vnum;i++)printf("%d ",color[i]);printf("\n");}void trycolor(int s,Graph G)/*s为开始图色的顶点,本算法从1开始*/ {int i;if(s>G.vnum)/*递归出口*/{output(G);exit(1);}else{for(i=1;i<=N;i++)/*对每一种色彩逐个测试*/{color[s]=i;if(colorsame(s,G)==0)trycolor(s+1,G);/*进行下一块的着色*/}}}int main(){Graph G;CreateGraph(G);PrintGraph(G);printf("着色方案:\n");trycolor(1,G);return 0;}四、运行主要结果界面贴图1、中国地图简略图2、取地图一部分进行测试有6个顶点,8条边。

世界地图为什么只有 4 种颜色?

世界地图为什么只有 4 种颜色?

世界地图为什么只有 4 种颜色?在一张世界地图上,要给相邻国家涂上不同的颜色,至少需要多少种颜色呢?答案是四种颜色。

这就是数学界非常有名的四色定理,这个最初源于给地图上国家上色的有趣问题被誉为世界近代三大数学问题之一。

数学家用了100 多年的时间才给出了真正的证明,所用的计算机证明也登上了数学舞台。

如今,在图论领域,还有许多由四色定理衍生出来的有趣问题。

例如,一个起源于收音机广播电台的问题:在一个无限大的网格纸上填入数字,同一个数字之间的“距离”必须大于这个数字本身,那么最少需要多少个数字能覆盖整个平面?年幼的你会对着书房墙面上的世界地图发呆吗?凝视着那五颜六色的图案,畅想着自己将来有一天能够环游世界。

而在 19 世纪的英国,一个古老且经典的数学问题——着色问题,就诞生于这样一份凝视。

应用四色定理填色的世界地图,图片来源:自然资源部标准地图服务系统四色问题的起源故事开始于 1852 年,英国地图制图师弗朗西斯·古特里(Francis Guthrie)在观察地图时提出了一个“给地图着色”的问题。

他发现只需要四种颜色就可以对地图进行着色,使得相邻的国家颜色不同。

但令他不解的是,这个数字“4”是否是最优的呢?于是他向他的弟弟弗雷德里克·古特里(Frederick Guthrie)及其朋友们寻求帮助。

在交流中,他们逐渐认识到这个问题与数学有着深刻的联系。

于是弗雷德里克向他的老师——伦敦大学学院的数学家奥古斯塔斯·德摩根(Augustus De Morgan)寻求帮助。

德摩根教授尝试之后也无能为力,于是写信将这个问题转交给了他的好友爱尔兰数学家威廉·哈密顿(William Hamilton)教授。

遗憾的是,充满智慧的哈密顿对这个问题并没有太大的兴趣。

摩尔根在信中写道:“一位学生今天让我说明一个事实,我们不知道它是否可作为一个事实。

他说将平面上的一个图形,任意划分成有限个部分并对其每个部分染色,使得相邻部分具有不同的颜色,而且只能用四种颜色。

地图着色问题课程设计

地图着色问题课程设计

地图着色问题课程设计一、课程目标知识目标:1. 理解地图着色问题的基本概念,掌握地图着色中涉及到的图论知识;2. 学会运用不同的算法解决地图着色问题,了解其优缺点;3. 掌握地图着色问题在实际生活中的应用,如行政区划、交通规划等。

技能目标:1. 能够运用所学知识,对给定的地图进行有效着色,提高解决问题的能力;2. 学会运用图论软件或工具进行地图着色的实际操作,培养动手实践能力;3. 通过团队合作,培养学生的沟通协调能力和解决问题的能力。

情感态度价值观目标:1. 激发学生对图论和地图着色问题的兴趣,培养良好的学习态度;2. 引导学生关注地图着色问题在实际生活中的应用,提高学生的社会责任感和实践意识;3. 培养学生面对复杂问题时,保持积极的心态,勇于克服困难,寻求解决问题的方法。

课程性质:本课程为数学学科选修课程,结合图论知识,以地图着色问题为载体,培养学生的逻辑思维能力和实际操作能力。

学生特点:学生处于高年级阶段,具备一定的数学基础和逻辑思维能力,对新鲜事物充满好奇心,具备一定的团队协作能力。

教学要求:注重理论与实践相结合,充分调动学生的积极性,引导学生主动参与课堂讨论和实践活动,提高学生的综合素养。

在教学过程中,将课程目标分解为具体的学习成果,以便于教学设计和评估。

二、教学内容1. 图论基础知识回顾:包括图的定义、图的表示方法、顶点和边的性质等;教材章节:第一章 图的基本概念2. 地图着色问题的提出:介绍地图着色的背景、意义及应用场景;教材章节:第二章 图的着色问题3. 地图着色算法:学习并掌握贪心算法、回溯算法、遗传算法等地图着色方法;教材章节:第三章 着色问题的算法及其应用4. 地图着色问题的实际操作:运用图论软件或工具进行地图着色实践;教材章节:第四章 着色问题的实际应用5. 地图着色问题案例分析:分析生活中的地图着色问题实例,如行政区划、交通规划等;教材章节:第五章 着色问题的案例分析6. 团队合作与交流:分组讨论、分享学习心得,培养学生的团队协作和沟通能力。

图的着色问题

图的着色问题

问题来源
图的着色
通常所说的着色问题是指下述两类问题: 通常所说的着色问题是指下述两类问题: 1.给定无环图G=(V,E),用m种颜色为图中 的每条边着色,要求每条边着一种颜色, 的每条边着色,要求每条边着一种颜色,并 使相邻两条边有着不同的颜色, 使相邻两条边有着不同的颜色,这个问题称 为图的边着色问题。 为图的边着色问题。 2.给定无向图G=(V,E),用m种颜色为图中 的每个顶点着色,要求每个顶点着一种颜色, 的每个顶点着色,要求每个顶点着一种颜色, 并使相邻两顶点之间有着不同的颜色, 并使相邻两顶点之间有着不同的颜色,这个 问题称为图的顶着色问题。 问题称为图的顶着色问题。
化简得
( a + bd )(b + aceg )(c + bdef )( d + aceg )(e + bcdf )( f + ceg )( g + bdf )
求极小覆盖法- 求极小覆盖法-布尔代数法
Step3:从中挑选所用极大独立集个数最小者, Step3:从中挑选所用极大独立集个数最小者, 即为X 即为X(G) 但上述子集的颜色数都不是X ),正确的应 但上述子集的颜色数都不是X(G),正确的应 该是X =3,该子集为: {b,d,f}中的 该是X(G)=3,该子集为:给{b,d,f}中的 b,d,f涂颜色 涂颜色1 {a,e,g}中a,e,g涂颜色 涂颜色2 b,d,f涂颜色1,为{a,e,g}中a,e,g涂颜色2为 {a,c,g}中的 涂颜色3 中的c {a,c,g}中的c涂颜色3。 由此可见, 由此可见,求色数其需要求极大独立集以 及一切若干极大独立集的和含所有顶点的子 对于大图, 集,对于大图,因为图计算量过大而成为实 际上难以凑效的算法,所以不是一个好算法, 际上难以凑效的算法,所以不是一个好算法, 一般我们采用贪心法等近似算法来求解 。

地图着色的四色猜想

地图着色的四色猜想

地图着色的四色猜想
人人都熟悉地图,可并不是人人都知道,绘制一张地图最少要用几种颜色,才能把相邻的国家或不同的区域区分开来。

这个地图着色问题,是一个著名的数学难题,它曾经吸引了好几代优秀的数学家为之奋斗,并且从中获得了一个又一个杰出的成就,为数学的发展增添了光辉。

在地图上区分两个相邻的国家或地区,要用不同的颜色来涂这两个国家或区域。

如上图表示某个国家的省区地图,图中虚线表示各省界。

可见,用两种颜色是区分不开的,三种颜色就够了。

A、B、C三省各用一色,D省和B省用同样的颜色。

又如上图所示的地图,1,2,3,4表示四个国家。

因为这张地图的四个国家中任何两个都有公共边界,所以必须用四种颜色才能把它们区分开。

于是,有的数学家猜想,任何地图着色只需四种颜色就足够了。

正式提出地图着色问题的时间是1852年。

当时伦敦大学的一名学生法朗西斯向他的老师、著名的数学家、伦敦大学数学教授莫根提出了这个问题。

莫根无法解答,求助于其他的数学家,也没能解决。

于是,这个问题一直传下来。

直到1976年9月,《美国数学会通告》宣布了一件需撼全球数学界消息:美国伊利诺斯大学的两位教授阿贝尔和哈根,利用电子计算机证明了地图的四色猜想是正确的! 他们将地图的四色问题化为2000个特殊的图的四色问题,然后在电子计算机上计算了1200个小时,终于证明了四色问题。

实验四 回溯法(图着色问题)

实验四 回溯法(图着色问题)
对应的邻接矩阵
01 234 001 1 01 1 1 01 01 21 1 01 0 3001 01 41 1 01 0
class MGraph { public:
MGraph(int v,int s); void mColoring(int m,int *x); //一维数组x,存放1~n个顶点的颜色 ~MGraph(); private: void NextValue(int k,int m,int *x); void mColoring (int k,int m,int *x); int **a; //二维数组a,存储图的邻接矩阵 int n,e; //n表示图的顶点数,e表示边数 };
无向图G
【实验内容与要求】
图的着色问题:设G=(V,E)是一连通无向图,有3 种颜色,用这些颜色为G的各顶点着色,每个顶点着 一种颜色,且相邻顶点颜色不同。试用回溯法设计一 个算法,找出所有可能满足上述条件的着色法。
无向图G
无向图G
对应这个无向图的状态空间树应该是怎样的?
是一个完全3叉树,共6层
实验四 回溯法 — 图的着色问题
图的着色问题是由地图的着色问题引申而来的: 用m种颜色为地图着色,使得地图上的每一个 区域着一种颜色,且相邻区域颜色不同。
问题处理:如果把每一个区域收缩为一个顶点, 把相邻两个区域用一条边相连接,就可以把一
个区域图抽象为一个平面图。
地图(map)中地区的相邻关系,在图(graph )中用边表示。
//若(i, j)是图的边,且相邻结点k和j颜色相同 //发生冲突,选下一种颜色
if (j==k) return; //成功选择一种颜色返回 }while (1); //循环尝试颜色 }
运行结果:

图的着色问题

图的着色问题

? 布尔恒等式
aa=a
?
a+a=a
? ? 如:
(ab ? bc)(a ? bd) ? aba ? abbd ? abc+a ?abbcb=da
? ab ? abd ? bcd ? bca ? bcd
? ab ? bcd
求极小覆盖法-布尔代数法
? 例1:求图12-2G的顶色数 解: ? Step1:求极大独立集
(可能有空的)独立集的一个分类(V1,V2,…,Vk)。当G有一个正常
k顶点着色时,就成G是k顶点可着色的。 ? G的色数X(G)是指G为k可着色的k的最小值,若X(G)=k,则称G
是k色的。 ? 事实上,如果我们将同色的顶点列入一个顶点子集,那么求X(G)
就转为求满足下列条件的最少子集数k: (1)两两子集中的顶点不同; (2)子集中的两两顶点不相邻。 显然有: (i)若G为平凡图,则X(G)=1;
问题来源
图的着色
? 通常所说的着色问题是指下述两类问题:
? 1.给定无环图G=(V,E),用m种颜色为图中
的每条边着色,要求每条边着一种颜色,并 使相邻两条边有着不同的颜色,这个问题称 为图的边着色问题。
? 2.给定无向图G=(V,E),用m种颜色为图中
的每个顶点着色,要求每个顶点着一种颜色 ,并使相邻两顶点之间有着不同的颜色,这 个问题称为图的顶着色问题。
穷举法-Welch Powell着色法
? I.将图G中的结点按度数的递减顺序进行排列 (
? 极小覆盖:极大独立集的补集称为极小覆盖。 V的子集K是G的极小覆盖当且仅当:对于每个顶 点v或者v属于K,或者v的所有邻点属于 K(但两 者不同时成立) 。
顶点着色-基本概念
? K可着色:G的一个k顶点着色是指k种颜色1,2,…,k对于G各顶点的 一个分配,如果任意两个相邻顶点都分配到不同的颜色,则称着色 是正常的。换句话说,无环图G的一个正常k顶点着色是把V分成k个
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

地图着色问题说明:任何平面区域图都可以用四种颜色着色,使相邻区域颜色互异。

这就是四色定理。

要求给定区域图排出全部可能的四着色方案。

区域相邻关系用矩阵表示,每个区域又一个序号,(从0七连续排列)adj【i】【j勘硎厩 騣,j相邻。

数组cilir记录每个区域上着的色,用1.2.3.4表示。

程序应包括四个函数:coloring对所给邻接矩阵找着全部着色方案色乐的:对区域i在指定的颜色范围内选出可选颜色或报告失败(失败返回-1)辞令次日卡:判断对区域i在指定的颜色c是否可用八寸卡:选色失败时或完成一种着色方案时进行回溯另外可定义output函数,每次输出一种着色方案/*递归算法:void Coloring(区域 n)1. 令颜色集ClrSet={ 没有被区域n的邻居区域使用的颜色 }.2. 如果ClrSet是空集,返回.3. 对ClrSet中的每种颜色c,作循环:3.1 为区域n着色c。

3.2 如果所有区域都已着色(n是最后一个区域),那么显示/保存着色结果.3.3 否则对下一个尚未着色的区域(n+1),调用Coloring(n+1).4. 把区域n变为没有着色的区域.--------------------------------------------------------*/template<int node_count = 8>class CColoring{private:typedef int node_type;typedef int color_type;typedef std::set<node_type> node_set;typedef std::vector<color_type> color_array;public:void operator()(const int _Matrix[node_count][node_count]){matrix = _Matrix;colors_of_nodes.resize(node_count, 0); total_count = 0;coloring(0);}private:void coloring(node_type n){// 颜色的使用情况std::vector<bool> used_colors;node_type m;color_type c;// 初始化颜色的使用情况used_colors.resize(color_count, false);// 遍历每个与区域n相邻的区域mfor(m = 0; m < node_count; ++m){if(matrix[n][m]){// 获取m的颜色c = colors_of_nodes[m];// m已着色if(c != 0)used_colors[c] = true;}}// 遍历每个未被n的邻居使用的颜色cfor(c = 1; c < color_count; ++c){if(!used_colors[c]){// 为n着色ccolors_of_nodes[n] = c;// 着色完毕if(n >= node_count - 1)++total_count;// 输出结果_tprintf(_T("---------------------\n"));_tprintf(_T("Method %d:\n"), total_count);for(m = 0; m < node_count; ++m){_tprintf(_T("node: %d, color: %d\n"), m, colors_of_nodes[m]); }}// 还有区域没有着色else{// 为下一个未着色的区域,调用coloring()coloring(n + 1);}}}// 将n设置为没有着色的区域colors_of_nodes[n] = 0;}// 0表示无色,1-4表示4种不同颜色static const int color_count = 5;// 邻接矩阵const int (* matrix)[node_count];// 各区域对应的颜色color_array colors_of_nodes;// 总的着色方案数int total_count;};void main(){int Matrix[4][4] ={{ 0, 1, 0, 0 },{ 1, 0, 0, 0 },{ 0, 0, 0, 1 },{ 0, 0, 1, 0 },};CColoring<4> coloring;coloring(Matrix);}/*递归算法:void Coloring(区域 n)1. 令颜色集ClrSet={ 没有被区域n的邻居区域使用的颜色 }.2. 如果ClrSet是空集,返回.3. 对ClrSet中的每种颜色c,作循环:3.1 为区域n着色c。

3.2 如果所有区域都已着色(n是最后一个区域),那么显示/保存着色结果.3.3 否则对下一个尚未着色的区域(n+1),调用Coloring(n+1).4. 把区域n变为没有着色的区域.--------------------------------------------------------*/template<int node_count = 8>class CColoring{private:typedef int node_type;typedef int color_type;typedef std::set<node_type> node_set;typedef std::vector<color_type> color_array;public:void operator()(const int _Matrix[node_count][node_count]){matrix = _Matrix;colors_of_nodes.resize(node_count, 0);total_count = 0;coloring(0);}private:void coloring(node_type n){// 颜色的使用情况std::vector<bool> used_colors;node_type m;color_type c;// 初始化颜色的使用情况used_colors.resize(color_count, false);// 遍历每个与区域n相邻的区域mfor(m = 0; m < node_count; ++m){if(matrix[n][m]){// 获取m的颜色c = colors_of_nodes[m];// m已着色if(c != 0)used_colors[c] = true;}}// 遍历每个未被n的邻居使用的颜色cfor(c = 1; c < color_count; ++c){if(!used_colors[c]){// 为n着色ccolors_of_nodes[n] = c;// 着色完毕if(n >= node_count - 1){++total_count;// 输出结果_tprintf(_T("---------------------\n"));_tprintf(_T("Method %d:\n"), total_count);for(m = 0; m < node_count; ++m){_tprintf(_T("node: %d, color: %d\n"), m, colors_of_nodes[m]);}}// 还有区域没有着色else{// 为下一个未着色的区域,调用coloring()coloring(n + 1);}}}// 将n设置为没有着色的区域colors_of_nodes[n] = 0;}// 0表示无色,1-4表示4种不同颜色static const int color_count = 5;// 邻接矩阵const int (* matrix)[node_count];// 各区域对应的颜色color_array colors_of_nodes;// 总的着色方案数int total_count;};void main(){int Matrix[4][4] ={{ 0, 1, 0, 0 },{ 1, 0, 0, 0 },{ 0, 0, 0, 1 },{ 0, 0, 1, 0 },};CColoring<4> coloring;coloring(Matrix);}1. 那个格式化过的代码里面,我用全角空格代替了制表符(tab),编译肯定不能通过,因为全角空格不是C++的空白符。

所以,你需要把全角空格替换成空格或制表符才行。

2. 那个代码没有写头文件,你需要包含stdio.h、tchar.h、set、vector这几个头文件。

如果你用的不是VC++,那么没有tchar.h,就别包含了,并且需要把程序中的_tprintf(_T(".."))改成printf("..")。

或者你干脆用iostream中的的cout。

3. 这个代码在VC++8.0下运行通过,不过即使是VC++6.0也应该没问题的。

相关文档
最新文档