文章目录

  • 图的m着色问题背景
    • 背景知识
    • 问题描述
  • 回溯法的原理及其实现
    • 回溯法基本思想
    • 朴素回溯法解决图的m着色问题
  • 回溯优化策略
    • 回溯法优化——变量排序MRV
    • 回溯法优化——值排序MCV
    • 回溯法优化——前向检查ForwardChecking
    • 边相容Arc consistency
    • 智能回溯AI Trackback
    • K阶相容
  • 资源下载
    • 实验伪代码下载
    • python源码下载
    • C++源码下载
    • 地图数据集下载
    • 授课用ppt下载

图的m着色问题背景

背景知识

为地图或其他由不同区域组成的图形着色时,相邻国家/地区不能使用相同的颜色。 我们可能还想使用尽可能少的不同颜色进行填涂。一些简单的“地图”(例如棋盘)仅需要两种颜色(黑白),但是大多数复杂的地图需要更多颜色。
       每张地图包含四个相互连接的国家时,它们至少需要四种颜色。1852年,植物学专业的学生弗朗西斯·古思里(Francis Guthrie)于1852年首次提出“四色问题”。他观察到四种颜色似乎足以满足他尝试的任何地图填色问题,但他无法找到适用于所有地图的证明。这个问题被称为四色问题。长期以来,数学家无法证明四种颜色就够了,或者无法找到需要四种以上颜色的地图。直到1976年德国数学家沃尔夫冈·哈肯(Wolfgang Haken)(生于1928年)和肯尼斯·阿佩尔(Kenneth Appel,1932年-2013年)使用计算机证明了四色定理,他们将无数种可能的地图缩减为1936种特殊情况,每种情况都由一台计算机进行了总计超过1000个小时的检查。
       他们因此工作获得了美国数学学会富尔克森奖。在1990年,哈肯(Haken)成为伊利诺伊大学(University of Illinois)高级研究中心的成员,他现在是该大学的名誉教授。
       四色定理是第一个使用计算机证明的著名数学定理,此后变得越来越普遍,争议也越来越小 更快的计算机和更高效的算法意味着今天您可以在几个小时内在笔记本电脑上证明四种颜色定理。

问题描述

我们可以将地图转换为平面图,每个地区变成一个节点,相邻地区用边连接,我们要为这个图形的顶点着色,并且两个顶点通过边连接时必须具有不同的颜色。附件是给出的地图数据,请针对三个地图数据尝试分别使用5个(le450_5a),15个(le450_15b),25个(le450_25a)颜色为地图着色。

回溯法的原理及其实现

回溯法基本思想

回溯法(backtracking)是暴力搜索法中的一种。对于某些计算问题而言,回溯法是一种可以找出所有(或一部分)解的一般性算法,尤其适用于约束补偿问题(在解决约束满足问题时,我们逐步构造更多的候选解,并且在确定某一部分候选解不可能补全成正确解之后放弃继续搜索这个部分候选解本身及其可以拓展出的子候选解,转而测试其他的部分候选解)。
       在图着色问题中,我们去尝试每个顶点可能的取值,保证两个邻接的顶点颜色不一致,是一个典型的约束满足问题,可以使用回溯法解决。
       回溯法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现,现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:
              A.找到一个可能存在的正确的答案
              B.在尝试了所有可能的分步方法后宣告该问题没有答案
       在最坏的情况下,回溯法会导致一次复杂度为指数时间的计算。

朴素回溯法解决图的m着色问题

给定无向连通图G=(V,E) 和 c种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点涂一种颜色。如果一个图最少需要c种颜色才能使图中每条边连接的2个顶点涂不同颜色,则称c为该图的色数。
       在这个问题的解决中,我们首先需要将实际的地图抽象成一个无向图,并为其建立邻接矩阵或者邻接表。如下图所示。

接着使用回溯法搜索求解,实际上是深度优先+变量分配+约束检查,算法简单描述为:
       A. 初始状态:所有变量为分配颜色;
       B. 后继函数:对未分配的变量分配一个值;
       C. 目标测试:变量都已分配值而且满足约束条件。
       实际上,回溯法=深度优先+变量分配+约束检查。

    def trackback(self):"""普通回溯算法:return: True: 有解 or False: 无解"""k = 0  # 递归层数while k >= 0:self.G[k].color = self.G[k].color + 1  # 给当前顶点涂色# 检查涂色是否合法,不合法则尝试其他颜色while self.G[k].color <= self.color_num:if self.check(k):breakelse:self.G[k].color = self.G[k].color + 1# 退出条件:所涂颜色合法并且达到最大递归深度if self.G[k].color <= self.color_num and k == self.depth:return True# 如果颜色合法,但还没达到最大递归深度,则继续递归求解elif self.G[k].color <= self.color_num and k < self.depth:k = k + 1# 否则回溯else:self.G[k].color = 0k = k - 1return False

回溯优化策略

回溯法优化——变量排序MRV

正如前面所说,回溯法如果只是无信息地盲目搜索,在最坏情况下需要达到指数级别的时间复杂度,这对个人笔记本来说就是一个灾难,根本无法求解。
       注意到,根据约束条件我们可以得到一定的启发式信息,利用这些启发式信息进行启发式的回溯搜索可以大大提高速度。而启发式算法一般都会采取剪枝的策略,这样就可以减少空间搜索树的分支,从而提高搜索速率。
       MRV正是针对这一思想出发的一种排序-预剪枝策略,其性能提升有时可以达到1000倍。MRV的思想是使得顶点失败最快,主要由两个部分构成排序规则:值域由少到多,度由大到小。即下一次选择的变量,尽可能选择取值最少的,受到其他变量约束最大的顶点,这样可以让其更快的失败,从而避免没有必要的搜索。下面两张图分别是最少可取值排序和度排序的例子。

def MRV_cmp(v1, v2):"""变量排序:可取值从少到多,相同的按照度从大到小排序:param v1: 顶点1:param v2: 顶点2:return: True or False"""if len(v1.legal_color) != len(v2.legal_color):return len(v1.legal_color) < len(v2.legal_color)else:return len(v1.adjacency) > len(v2.adjacency)

回溯法优化——值排序MCV

上面讲了怎么选取变量,一旦变量选好了,变量的值应该怎么选呢?
最少约束值:优先选择的赋值是给邻居变量留下更多的选择
下图中,右上角的Q应选择红色,若选择蓝色,则SA没有可选的颜色了

回溯法优化——前向检查ForwardChecking

除了预剪枝之外,我们还可以利用约束条件在搜索过程中进行剪枝,这便是前向检查,前向检查的思想为检查未分配变量的合法剩余值,当任何变量没有合法值时终止。

上图中,长条形颜色表示给对应地图上色,正方形颜色表示未上色,但是可以选择的合法颜色,按顺序对WA,Q,V赋值后,SA值域为空,故算法立刻回溯。
       前向检验能检测出很多不相容,但是它无法检测所有不相容。它使当前变量边相容,但是并不向前看使其他变量边相容。上图中第三行,当WA,Q都赋值后,NT和SA都只能是蓝色了。前向检验向前看得不够远,不足以观察出这种不相容;NT和SA邻接所以不能取相同的值。

def forward_checking(vex, color):"""前向检查:将违反约束的现有已分配合法颜色去掉,只检查尚未涂色的邻接点:param vex: 顶点:param color: 颜色:return: 改变了合法颜色取值范围的邻接点id"""record = []# 遍历邻接点for k in range(0, len(vex.adjacency)):# 寻找尚未涂色的邻接点if vex.adjacency[k].color == 0:# 判断是否需要缩小取值范围for j in range(0, len(vex.adjacency[k].legal_color)):if vex.adjacency[k].legal_color[j] == color:del vex.adjacency[k].legal_color[j]record.append(k)breakreturn record

def forward_recover(vex, color, record):"""前向检查恢复,与前向检查对应:param vex: 顶点:param color: 颜色:param record: 前向检查影响的邻接点id"""for i in range(0, len(record)):vex.adjacency[record[i]].legal_color.append(color)

边相容Arc consistency

边相容的提出,主要是为了解决前向检查看的不够远的问题,其思想是:当变量X赋值后,边相容从与X相邻的弧中所有其他没有赋值的变量出发,若一旦某个变量的值域变为空,则算法立刻回溯。

上图中,当WA,Q都赋值后,边相容算法可以检测和SA邻接的NT的取值。若NT没有可取的值,则回溯。
       边相容检测故障早于前向检查。

智能回溯AI Trackback

智能回溯的思想是:当涂色失败时,回溯到与失败顶点最近冲突的顶点。

在上图中,如果按照之前的时序回溯到T,我们给T换一种颜色,继续涂色SA,还是会发生冲突。因此我们给SA建立一个冲突及{Q,NSW,W,V},我们需要回溯到最近冲突的顶点,即V。
       智能回溯的意义在于,可以减少不必要的尝试,直接回溯到能够解决问题的顶点,其性能在一般情况下可以提高将近20倍。

 def MRV_ForwardChecking_AItrackback(self, dep, conflict):"""回溯策略:1. 变量排序:可取值由少到多,顶点的度由大到小,也称预剪枝策略之一2. 前向检查:将违反约束的现有已分配合法颜色去掉3. 智能回溯:区别于时序回溯,智能回溯是失败时回溯到最近冲突的点:param dep: 当前递归深度:param conflict: 与失败顶点邻接的顶点id:return: True: 有解 or False: 无解"""# 如果当前深度已经达到最大递归深度,说明已经求得解if dep > self.depth:return Trueself.G.sort(key=cmp_to_key(MRV_cmp))  # 排序# 如果当前顶点无合法取值,则失败返回if len(self.G[dep].legal_color) == 0:conflict = self.G[dep].adjId  # 记录失败顶点的邻接点return Falseself.visited.append(self.G[dep].id)  # 将当前顶点放入已访问顶点集中# 遍历合法取值,每一个都去尝试for i in range(0, len(self.G[dep].legal_color)):self.G[dep].color = self.G[dep].legal_color[i]  # 涂色record = forward_checking(self.G[dep], self.G[dep].color)  # 前向检查# 递归回溯if self.MRV_ForwardChecking(dep + 1):return Trueelse:forward_recover(self.G[dep], self.G[dep].color, record)  # 前向恢复conflict_id = list(set(conflict).intersection(set(self.visited)))  # 求出冲突集# 如果当前顶点不在冲突集中,则继续回溯, 智能回溯主体if self.G[dep].color not in conflict_id:self.G[dep].color = 0del self.visited[-1]return False# 如果没有匹配的值,置当前颜色为0,返回falseself.G[dep].color = 0conflict = self.G[dep].adjIddel self.visited[-1]  # 失败回溯return False

K阶相容

K阶相容的含义是:在每K个变量中,两两都满足约束条件,特别地1阶相容是顶点相容,2阶相容是边相容,3阶相容是路径相容,强K阶相容(当K等于顶点数时)意味着无需回溯就可以求解问题。但是随着K的增大,计算的代价也相应增大。在本实验中,选择K=3可以得到比较好的结果。

资源下载

实验伪代码下载

Latex伪代码下载

python源码下载

python源码下载

C++源码下载

C++源码下载

地图数据集下载

测试数据-莱顿图和随机平面图下载

授课用ppt下载

ppt下载

注意:以上资源只作为学术交流,请勿将文中任何资料用作商业用途或者作业提交。版权所有,引用请注明出处。

图的m着色问题——回溯法及其优化(变量排序MRV, 值排序MCV, 前向检查ForwardChecking, 智能回溯, 边相容,K阶相容)python C++实现相关推荐

  1. 力扣638. 大礼包(回溯法+剪枝优化)

    第八十八天 --- 力扣638. 大礼包 题目一 思路:回溯法 代码 无剪枝的回溯 剪枝优化 Sum Up 题目一 力扣:力扣638. 大礼包 思路:回溯法 1.我们先不考虑礼包,直接去买东西,就是物 ...

  2. 【有返回值的回溯法】剑指offer——面试题66:矩阵中的路径(回溯法)

    剑指offer--面试题66:矩阵中的路径(回溯法) Solution:1 典型的回溯算法及代码 此题是回溯法的典型例题,思路以及代码均是书中所讲.要具体实现很有参考价值,借鉴之! 现在把书中代码贴在 ...

  3. python做马尔科夫模型预测法_隐马尔可夫模型的前向算法和后向算法理解与实现(Python)...

    前言 隐马尔可夫模型(HMM)是可用于标注问题的统计学习模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型. 马尔可夫模型理论与分析 参考<统计学习方法>这本书,书上已经讲得 ...

  4. 【算法分析】实验 4. 回溯法求解0-1背包等问题

    目录 实验内容 实验目的 实验结果 步骤1:描述与分析 步骤2:策略以及数据结构 步骤3 步骤4 步骤5 步骤6 实验总结 实验内容 本实验要求基于算法设计与分析的一般过程(即待求解问题的描述.算法设 ...

  5. 【算法学习笔记】16.暴力求解法04 回溯法03 剪枝法 带宽

    在之前的 N 皇后和困难的串问题中,回溯法都是在解决可行性约束.换一句话说,对于回溯点的判断是用来验证此点是否合法. 但是在一些优化问题的求解过程中,每一个点都是合法的,所以我们要进行剪枝. 1.先得 ...

  6. 回溯法求解N皇后问题及其时间复杂度分析

    回溯法求解N皇后问题及其时间复杂度分析 一.回溯法简介 1. 什么是回溯法? 2. 回溯法的时间复杂度分析 蒙特卡罗方法 蒙特卡罗方法在回溯法求解时间复杂度中的应用 二.回溯法求解N皇后问题 1. 回 ...

  7. 算法设计与分析 实验三 回溯法求解地图填色问题

    回溯法求解地图填色问题 一.实验目的与要求 1.实验基本要求: 2.实验亮点: 二.实验内容与方法 三.实验步骤与过程 1.未优化的回溯: (1)算法描述: (2)编程实现 (3)运行并测试: 2.对 ...

  8. java背包算法回溯法_【算法分析】实验 4. 回溯法求解0-1背包等问题

    [TOC] 实验内容 本实验要求基于算法设计与分析的一般过程(即待求解问题的描述.算法设计.算法描述.算法正确性证明.算法分析.算法实现与测试),通过回溯法的在实际问题求解实践中,加深理解其基本原理和 ...

  9. 消消乐实验回溯法(深大算法实验3)报告+代码

    实验代码 + 报告资源: 链接: https://pan.baidu.com/s/1CuuB07rRFh7vGQnGpud_vg 提取码: ccuq 目录 写在前面 实验要求 求解问题的算法原理描述 ...

最新文章

  1. 多股Litz线制作无线耦合线圈测试
  2. pod install 失败 Сocoapods trunk URL couldn't be downloaded
  3. VS2012生成ReactOS的VS工程失败(三)和 “ cl is not able to compile a simple test program“错误
  4. Gym 101334F Feel Good
  5. Java实现字母的大小写转换
  6. LeetCode 2157. 字符串分组(状态压缩+位运算+图的遍历)
  7. MATLAB实现BP神经网络预测汽油辛烷值
  8. AJAX 中Sys.WebForms.PageRequestManager的事件激发顺序
  9. 淘宝技术发展(引言)、技术发展(个人网站)
  10. AWS AI网络研讨会 - Data Lab案例分享
  11. c iostream.源码_通达信三线注意买入主图指标公式【源码分享】
  12. SpringBoot添加FastJson消息转换器(自用)
  13. 如何将EXCEL中的多个单元格内容合并在一个单元格内
  14. 福莱特法公式matlab,浙江省公路出行交通分布模型研究
  15. Android Interpolator(插值器)的介绍和使用
  16. 提高ubuntu下访问github的速度
  17. 背包DP FOJ 2214
  18. 第三章 页表管理(Page Table Management)
  19. 直接在内存里计算数据?先做一个内存数据库技术选型吧
  20. 视频教程-JAVAEE真实课堂之MySQL数据库-云计算基础架构

热门文章

  1. 为什么增加解释变量的个数,R^2不会减小,该如何证明
  2. wget 命令 简单使用
  3. H3 BPM工作流 javaScript 页面展示问题
  4. mysql-workbench工具update(更新)失败的解决办法
  5. 一次平平无奇的UDP维修过程
  6. 【算法学习】欧几里得算法详解(包括扩展、同余方程)
  7. 中控系统html5模版,展馆中控程序(含文档)
  8. mysql 巡检日志模板_Oracle数据库巡检分析报告模板【企业实战巡检】
  9. idea中出现紫色_紫色测试和安全性实验中的混乱工程
  10. 网站下载视频是php格式错误,为什么优酷下载的(.kux)格式视频转码总提示我“错误”?求答!...