地图着色,需要每一个区域都使用一种颜色来进行填充,然后为了与相邻接壤的区域分开,就要求两个接壤的区域需要使用不同的颜色。四色定理的意思是,最多只需要四种颜色,就可以为所有的地图进行全部区域着色,且任意两个接壤的区域都是不同的颜色。在四色定理的指导下,我用Java来实现求解任意一副地图的所有可行的区域着色方案的算法,并求解下面这幅示例地图的所有着色方案:

算法思路:

  1. 将所有的区域进行编号,从0开始,然后用一个长度为区域总数的数组记录,称为颜色方案数组
  2. 颜色方案数组的下标是区域编号,值是使用的颜色,代号为1、2、3、4四种颜色。初始化全部是0,也就是颜色0代表未着色,如果大于0,代表已着色,值就是颜色
  3. 创建无权无向图,所有区域映射图的顶点,如果两个区域是接壤的,则对应图的两个顶点之间就是连通的,然后求出该无权无向图的记录有地图区域接壤关系的邻接矩阵
  4. 0区域默认使用1号颜色,然后找到下一个区域,根据接壤关系的邻接矩阵和颜色方案数组,找到下一个区域的所有接壤区域已经使用过的颜色集,再反向求出可使用的颜色集
  5. 如果下一个区域的可使用颜色集为空集,则当前递归分支结束。如果不为空集,则遍历所有可用颜色,然后递归调用,一个可用颜色为一个递归分支,着色下一个区域……
  6. 递归方法在着色后进行判断,如果刚刚着了色的区域已经是最后一个区域了,则表示程序已经找到了地图着色方案。然后程序输出颜色方案数组,以展示可行的地图着色方案

第一步:将所有的区域进行编号,从0开始

第二步:创建无权无向图,所有区域映射图的顶点,如果两个区域是接壤的,则连通对应图的两个顶点

3、根据上面记录有地图区域接壤关系的无权无向图,求出该图的邻接矩阵。该邻接矩阵也是算法输入的数据来源

下面是我用Java实现的求解上面示例图的着色方案的算法。该算法的思想和精髓已经在下面的代码和其间的详尽注释中:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;/*** @author LiYang* @ClassName FourColorTheorem* @Description 四色定理探索实践类* @date 2019/12/7 22:32*/
public class FourColorTheorem {//根据四色定理,最多只使用四种颜色,就可以为任何地图//着色,并且保证相邻接壤的区域必须用不同的颜色//---------------------------------------------//注意,如果你的地图足够特别,也是有可能三种,甚至更少//的颜色种类就完成着色,此时可以将下面的数字改小,然后//查看控制台是否有结果输出,有结果输出则表示可行private static final int MIN_NECESSARY_MAP_COLOR = 4;/*** 返回示例地图接壤信息的邻接矩阵* @return 示例地图接壤信息的邻接矩阵*/public static int[][] initMapMatrix() {//直接返回记录示例地图接壤信息的邻接矩阵//要运行自己的地图,可以修改此邻接矩阵return new int[][] {{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},{1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},{1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0},{0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1},{0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0},{0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0},{0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1},{0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1},{0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0}};}/*** 深拷贝数组* @param source 数组拷贝源* @return 数组副本*/public static int[] copyArray(int[] source) {//创建新的数组int[] copy = new int[source.length];//拷贝赋值新数组System.arraycopy(source, 0, copy, 0, source.length);//返回深拷贝的副本return copy;}/*** 地图区域着色算法的递归执行方法* @param nextArea 着色区域* @param color 着色使用的颜色* @param colorPlan 着色计划记录数组* @param matrix 区域接壤的邻接矩阵*/public static void coloringMap(int nextArea, int color, int[] colorPlan, int[][] matrix) {//将当前区域着色colorPlan[nextArea] = color;//如果已经全部着色,则打印结果if (nextArea == colorPlan.length - 1) {//打印当前递归分支的着色方案System.out.println("找到着色方案:" + Arrays.toString(colorPlan));//结束当前递归分支return;}//当前区域更新为下一个区域//准备为下一个区域进行着色nextArea ++;//下一个区域的可用颜色集Set<Integer> availableColor = new HashSet<>();//初始化可用颜色集for (int i = 1; i <= MIN_NECESSARY_MAP_COLOR; i++) {//先全部加入,再用排除法去掉周边接壤颜色availableColor.add(i);}//遍历邻接矩阵,找到下一个区域的所有接壤区域for (int i = 0; i < matrix.length; i++) {//如果当前区域接壤,且已经着色if (matrix[nextArea][i] > 0 && colorPlan[i] > 0) {//将接壤的已用颜色剔除availableColor.remove(colorPlan[i]);}}//遍历下一个区域的所有可用颜色for (int available : availableColor) {//分别递归调用本算法,尝试下一个区域着所有可用颜色集coloringMap(nextArea, available, copyArray(colorPlan), matrix);}}/*** 地图区域着色算法的驱动方法* @param matrix 地图接壤的邻接矩阵*/public static void coloringMap(int[][] matrix) {//我们从0号区域开始,从哪个区域开始都一样int nextArea = 0;//颜色代号是1-4,本质是等价可互换的,用1开始就行int color = 1;//初始化着色方案int[] colorPlan = new int[matrix.length];//调用地图区域着色算法的递归执行方法coloringMap(nextArea, color, colorPlan, matrix);}/*** 运用四色定理,运行示例地图着色的算法* @param args*/public static void main(String[] args) {//获得记录示例地图接壤关系的邻接矩阵int[][] matrix = initMapMatrix();//运行示例地图着色的算法,并从控制台//查看打印的着色方案coloringMap(matrix);}}

运行FourColorTheorem类的main方法,控制台输出了很多可行的示例图着色方案!下面是我随意摘选的一部分示例图着色方案:

找到着色方案:[1, 2, 2, 3, 1, 1, 2, 3, 4, 2, 3]
找到着色方案:[1, 3, 2, 4, 2, 1, 3, 4, 2, 3, 4]
找到着色方案:[1, 4, 2, 4, 2, 1, 4, 3, 2, 1, 4]
找到着色方案:[1, 4, 4, 3, 3, 2, 4, 1, 3, 2, 1]

接下来我们验证算法求出的示例图着色方案。1号我们用红色,2号用黄色,3号用蓝色,4号用粉色,验证上面我随意筛选的四种示例图着色方案,地图着色后表明,该算法测试通过:

算法:根据四色定理(Four color theorem),求出地图的所有着色方案相关推荐

  1. 平面内有N个点,如何快速求出距离最近的点对?

    大家好,我们今天来看一道非常非常经典的算法题--最近点对问题. 这个问题经常在各种面试当中出现,难度不低,很少有人能答上来.说实话,我也被问过,因为毫无准备,所以也没有答上来.是的,这道题有点神奇,没 ...

  2. 机器学习与深度学习——通过knn算法分类鸢尾花数据集iris求出错误率并进行可视化

    什么是knn算法? KNN算法是一种基于实例的机器学习算法,其全称为K-最近邻算法(K-Nearest Neighbors Algorithm).它是一种简单但非常有效的分类和回归算法. 该算法的基本 ...

  3. 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较)

    本文目标是通过使用SIFT和RANSAC算法,完成特征点的正确匹配,并求出变换矩阵,通过变换矩阵计算出要识别物体的边界(文章中有部分源码,整个工程我也上传了,请点击这里). SIFT算法是目前公认的效 ...

  4. 【算法】广度遍历算法的应用 求出距离顶点v0的最短路径长度为最长的一个顶点,图结构的bfs生成树及其双亲表示形式

    例: 求出距离顶点v0的最短路径长度为最长的一个顶点,并要求尽可能节省时间 分析: 用bfs算法(利用bfs算法的层次特性): 从v0出发进行广度遍历时, 最后一层的顶点距离v0的最短路径长度最长.因 ...

  5. C语言使用1到9求出所有k个数字的所有组合的算法(附完整源码)

    C语言使用1到9求出所有k个数字的所有组合的算法 C语言使用1到9求出所有k个数字的所有组合的算法完整源码(定义,实现,main函数测试) C语言使用1到9求出所有k个数字的所有组合的算法完整源码(定 ...

  6. 判断素数或者求出素数的基本算法 《挑战程序设计竞赛》

    2018-2-28 首先我们得明确一个概念,那就是什么是素数,据我的了解,素数就是除了1和它本身之外,不存在其他的因数的数. 1.素性测试 判断给定的数n是否是素数 这应该是最简单的了,直接从2至n, ...

  7. php算法求出一个数可以被分解成多少个_小学奥数必须掌握的30个知识模块汇总...

    关注成长教育  解决学习困惑 点击蓝字关注,与全国家长比肩同行 1.和差倍问题和差问题 和倍问题 差倍问题已知条件 几个数的和与差 几个数的和与倍数 几个数的差与倍数公式适用范围 已知两个数的和,差, ...

  8. php算法求出一个数可以被分解成多少个_最全的小学干货:34个数学重难点公式(三)...

    1.和差倍问题: 和差问题 和倍问题 差倍问题 已知条件 几个数的和与差 几个数的和与倍数 几个数的差与倍数 公式适用范围 已知两个数的和,差,倍数关系 公式 ①(和-差)÷2=较小数 较小数+差=较 ...

  9. php算法求出一个数可以被分解成多少个_小学数学必考的34个数学重难点公式,赶紧给孩子收藏!...

    34个小学数学重难点公式 1.和差倍问题 2.年龄问题的三个基本特征 ①两个人的年龄差是不变的: ②两个人的年龄是同时增加或者同时减少的: ③两个人的年龄的倍数是发生变化的: 3.归一问题的基本特点 ...

最新文章

  1. 【深度学习笔记】分类指标accuracy,recall,precision等的区别
  2. 关于camera 构架设计的一点看法
  3. MySQL双主io线程起不来_解决master and slave have equal MySQL server UUIDs导致Slave_IO_thread起不来问题...
  4. Network in Network----Global Average Pooling
  5. Anaconda——conda换源可以直接通过conda命令来实现
  6. Android Multimedia框架总结(十八)Camera2框架从Java层到C++层类关系
  7. 有哪些实用的电脑软件值得推荐?2021电脑装机必备便签软件
  8. DRF如何使用serializer进行验证数据
  9. html记忆游戏,html5 最强大脑最强记忆游戏
  10. C#的GPU加速方法
  11. 第十二届蓝桥杯 2021年省赛真题 (Java 大学A组) 第一场
  12. python矩阵求和, numpy.sum()
  13. Canal Java 入门与使用
  14. vue中created、mounted、activated的区别
  15. mysql怎么禁用安全模式_mysql开启和关闭安全模式
  16. 王者荣耀服务器什么时候增加人数,王者荣耀正式服凌晨更新,新增几个细节改动...
  17. [译]用R语言做挖掘数据《四》
  18. 源码交易网站高仿站源网
  19. npm包管理的一个小错误, No repository field,No description
  20. HTML5+app开发学习之打包配置文件介绍篇

热门文章

  1. 计算机科学中的递归算法是把问题,从计算思维的视角辨析算法中的递归与迭代...
  2. js截取url问号前面_JS获取URL中问号后面参数值
  3. Leetcode 变位词组
  4. LDPC译码:和积译码算法(SPA)、最小和算法(MSA)、分层译码算法(LBP)、动态信息更新策略IDS(含RBP、NW-RBP、SVNF-RBP)的MATLAB实现
  5. 2018四川省排名前十的卫校名单有哪些?
  6. 第三方、第四方扫二维码的支付平台有哪些?
  7. Unity 绘制物体运动轨迹
  8. 【算力网络】算力网络的技术创新——绿色与安全关键技术
  9. Matlab:设置命令历史记录预设项
  10. jmeter 压力测试各种值的意思