目录
一、实验目的
1. 掌握回溯法算法设计思想。
2. 掌握地图填色问题的回溯法解法。
二、背景知识
为地图或其他由不同区域组成的图形着色时,相邻国家/地区不能使用相同的颜色。我们可能还想使用尽可能少的不同颜色进行填涂。一些简单的“地图”(例如棋盘)仅需要两种颜色(黑白),但是大多数复杂的地图需要更多颜色。
每张地图包含四个相互连接的国家时,它们至少需要四种颜色。1852年,植物学专业的学生弗朗西斯·古思里(Francis Guthrie)于1852年首次提出“四色问题”。他观察到四种颜色似乎足以满足他尝试的任何地图填色问题,但他无法找到适用于所有地图的证明。这个问题被称为四色问题。长期以来,数学家无法证明四种颜色就够了,或者无法找到需要四种以上颜色的地图。直到1976年德国数学家沃尔夫冈·哈肯(Wolfgang Haken,生于1928年)和肯尼斯·阿佩尔(Kenneth Appel,1932年-2013年)使用计算机证明了四色定理,他们将无数种可能的地图缩减为1936种特殊情况,每种情况都由一台计算机进行了总计超过1000个小时的检查。他们因此工作获得了美国数学学会富尔克森奖。在1990年,哈肯成为伊利诺伊大学高级研究中心的成员,他现在是该大学的名誉教授。
四色定理是第一个使用计算机证明的著名数学定理,此后变得越来越普遍,争议也越来越小。更快的计算机和更高效的算法意味着今天您可以在几个小时内在笔记本电脑上证明四种颜色定理。
三、实验内容
1. 用4色填色下面的这个小规模地图,测试算法的正确性。将其转换为平面图,每个地区表示为一个顶点,相邻地区用边连接,对这个图的顶点着色,并且相邻的两个顶必须使用不同的颜色。
图1 测试算法正确性的小规模地图
2. 分别读入附件中的3个图文件le450_5a.col, le450_15b.col, le450_25a.col,其中,le450_5a.col中的图用5色着色,le450_15b.col中的图用15色着色,le450_25a.col中的图用25色着色,测试3个图文件对应的算法运行时间,并将着色结果输出到文本中(按照顶点序号输出每个顶点的颜色,每个颜色占1行,颜色用1, 2, 3, …表示,着色结果文件名为相应的图文件名加上后缀out,即分别为le450_5a.col.out, le450_15b.col.out, le450_25a.col.out),运行附件中的check.exe程序测试着色结果是否正确。在公共的Linux服务器上测试该项实验内容,实验课时检查,步骤如下:
(i) 在文件资源管理器中打开ftp://hpc.szu.edu.cn,输入用户名algo,密码szu@1983,在当前目录下新建一个子目录,目录名为自己学号,将算法代码重命名为a.cpp,将算法代码和3个图文件都上传到该目录中。
(ii) 打开Windows PowerShell,执行命令ssh algo@hpc.szu.edu.cn,输入密码szu@1983;再执行命令ssh A1,登录到A1机器上;进入自己的目录,执行命令g++ -O3 -fopenmp -o a.out a.cpp生成可执行程序a.out,再执行命令./a.out运行算法程序。
(iii) 在4分钟内完成该项测试,必须保证着色结果正确,可以只测试3个图文件中的部分图文件,尽可能优化算法,提高算法效率。
3. 随机产生不同规模的图,用4色着色,分析算法效率与图规模的关系。
四、算法思想
描述回溯法思想求解地图填色问题的思想,采用了哪些方法以提高算法效率。
未优化的回溯算法
首先使用简易回溯算法,用4色填色下面的这个小规模地图,测试算法的正确性。对于给定的地图,我先将其 转换为平面图,每个地区表示为一个顶点,相邻地区用边连接,方便后续对地图的处理,抽象化后的地图如下所示。
回溯算法描述
回溯法的思想就是从根结点出发深度探索解空间树。当探索到某一结点时,判断该结点是否包含问题的解。如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则向其祖先结点回溯。
算法实现
拓展当前节点,并对当前节点进行搜索
判断当前节点是否存在可行解,如果存在则进入c,如果不存在,则回溯上一节点,并进入a
判断是否搜索结束,如果结束则直接输出结果并停止搜索;如果未结束,则进入a
当全部搜索完毕后仍不存在可行解,则输出无解
代码模板格式
回溯算法的优化
由于朴素的回溯算法效率太低,并无法在短时间内找到可行解,因此我们需要想办法优化回溯算法,提高回溯效率。
在本实验中,我主要从节点选择,颜色选择以及数据结构选择三个方面来考虑剪枝优化的方法。
节点选择-最小剩余值准则(MRV)
算法描述
在节点选择方面,我优先考虑的使最小剩余值准则,即MRV。
MRV算法的内核在于在每次选择变量时,会优先选择剩余可选颜色数量最少的未染色节点进行搜索,即选择当前可用颜色最少的节点,这样便可以达到在进行搜索分层的早期尽可能减少搜索分支的数量,但不满足涂色要求(即满足剪枝条件)时,将其直接剪掉,省去了许多后面分支多的无用比较,从而大幅减少搜索空间,达到提高算法的效率。
优化前搜索情况
优化后搜索情况
无论是从那个点开始搜索,得到的可行解是不变的,因此从度数较大的点开始搜索可以提升运行效率
具体实现
初始化未染色的区域列表和每个区域的可选颜色列表。
计算每个未染色的区域的可选颜色数量,按照可选颜色数量从小到大排序(通过每个节点的度进行比较)。
选择可选颜色数量最小的未染色区域进行分支,尝试每个可选颜色,直到找到一种可行的颜色。
如果某个未染色区域的可选颜色数量为0,则回溯到上一个已染色的区域,并重新选择分支的颜色。
如果所有区域都已染色,则得到了问题的一个解。