科百科
当前位置: 首页 科技资讯

python图像对比算法(Python实现基于地图四色原理的遗传算法)

时间:2023-06-05 作者: 小编 阅读量: 3 栏目名: 科技资讯

本文介绍利用Python语言,实现基于遗传算法的地图四色原理着色操作。具体分步骤思路如下:定义“规则”。“规则”用以将区域之间的空间连接情况转换为遗传算法可以识别的信息;被“规则”连接的两个区域在空间中是相邻的。通过个体的不断更迭,选择出满足“规则”要求的个体基因型。检查所得到的颜色与最优个体基因组中的各个基因是否一致。

本文介绍利用Python语言,实现基于遗传算法(GA)的地图四色原理着色操作。

1 任务需求

首先,我们来明确一下本文所需实现的需求。

现有一个由多个小图斑组成的矢量图层,如下图所示;我们需要找到一种由4种颜色组成的配色方案,对该矢量图层各图斑进行着色,使得各相邻小图斑间的颜色不一致,如下下图所示。

在这里,我们用到了四色定理(Four Color Theorem),又称四色地图定理(Four Color Map Theorem):如果在平面上存在一些邻接的有限区域,则至多仅用四种颜色来给这些不同的区域染色,就可以使得每两个邻接区域染的颜色都不一样。

2 代码实现

明确了需求,我们就可以开始具体的代码编写。目前国内各大博客中,有很多关于Python实现地图四色原理着色的代码,其中大多数是基于回溯法来实现的;而在一个英文博客网页中,看到了基于遗传算法的地图四色原理着色实现。那么就以该代码为例,进行操作。在这里,由于我本人对于遗传算法的理解还并不深入,因此在代码介绍方面或多或少还存在着一定不足,希望大家多多批评指正。

2.1 基本思路

遗传算法是一种用于解决最佳化问题的搜索算法,属于进化算法范畴。结合前述需求,首先可以将每一个区域的颜色作为一个基因,个体基因型则为全部地区(前述矢量图层共有78个小图斑,即78个区域)颜色基因的汇总;通过构建Rule类,将空间意义上的“相邻”转换为可以被遗传算法识别(即可以对个体基因改变加以约束)的信息;随后,结合子代的更替,找到满足要求的基因组;最终将得到的基因组再转换为空间意义上的颜色信息,并输出结果。

具体分步骤思路如下:

  1. 定义“规则”。“规则”用以将区域之间的空间连接情况转换为遗传算法可以识别的信息;被“规则”连接的两个区域在空间中是相邻的。
  2. 定义区域空间连接情况检查所需函数。这些函数用于检查两两区域之间的连接性是否满足逻辑;例如,若在“规则”中显示区域A与区域B连接,那么区域B也必须在“规则”中显示与区域A连接。
  3. 定义个体基因型。其中,各个体具有78个基因,每一个基因表示一个区域的颜色。
  4. 个体更替与最优基因选择。通过个体的不断更迭,选择出满足“规则”要求的个体基因型。
  5. 基因型解释。将得到的个体基因型进行解释,相当于第一步的反过程,即将基因信息转换为空间连接情况。
  6. 结果检查。检查所得到的颜色与最优个体基因组中的各个基因是否一致。
2.2 代码讲解

接下来,将完整代码进行介绍。其中,shapefile_path即为矢量图层的保存路径;"POLY_ID_OG"则为矢量图层的属性表中的一个字段,其代表每一个小图斑的编号。

# -*- coding: utf-8 -*-"""Created on Sun Oct 31 19:22:33 2021@author: Chutj"""import geneticimport unittestimport datetimefrom libpysal.weights import Queenshapefile_path="G:/Python_Home1/stl_hom_utm.shp"weights=Queen.from_shapefile(shapefile_path,"POLY_ID_OG")one_neighbor_other=weights.neighbors# 定义“规则”,用以将区域之间的空间连接情况转换为遗传算法可以识别的信息。被“规则”连接的两个区域在空间中是相邻的class Rule:Item = NoneOther = NoneStringified = Nonedef __init__(self, item, other, stringified):self.Item = itemself.Other = otherself.Stringified = stringifieddef __eq__(self, another):return hasattr(another, 'Item') and \hasattr(another, 'Other') and \self.Item == another.Item and \self.Other == another.Otherdef __hash__(self):return hash(self.Item) * 397 ^ hash(self.Other)def __str__(self):return self.Stringified# 定义区域空间连接情况检查所需函数,用以确保区域两两之间相邻情况的准确def buildLookup(items):itemToIndex = {}index = 0for key in sorted(items):itemToIndex[key] = indexindex= 1return itemToIndexdef buildRules(items):itemToIndex = buildLookup(items.keys())rulesAdded = {}rules = []keys = sorted(list(items.keys()))for key in sorted(items.keys()):keyIndex = itemToIndex[key]adjacentKeys = items[key]for adjacentKey in adjacentKeys:if adjacentKey == '':continueadjacentIndex = itemToIndex[adjacentKey]temp = keyIndexif adjacentIndex < temp:temp, adjacentIndex = adjacentIndex, tempruleKey = str(keys[temp])"->"str(keys[adjacentIndex])rule = Rule(temp, adjacentIndex, ruleKey)if rule in rulesAdded:rulesAdded[rule]= 1else:rulesAdded[rule] = 1rules.append(rule)for k, v in rulesAdded.items():if v == 1:print("rule %s is not bidirectional" % k)return rules# 定义颜色所代表的基因组colors = ["Orange", "Yellow", "Green", "Blue"]colorLookup = {}for color in colors:colorLookup[color[0]] = colorgeneset = list(colorLookup.keys())# 定义个体基因型,其中各个体有78个基因,每一个基因代表一个区域。个体基因需要满足“规则”中相邻的区域具有不同的颜色class GraphColoringTests(unittest.TestCase):def test(self):rules = buildRules(one_neighbor_other)colors = ["Orange", "Yellow", "Green", "Blue"]colorLookup = {}for color in colors:colorLookup[color[0]] = colorgeneset = list(colorLookup.keys())optimalValue = len(rules)startTime = datetime.datetime.now()fnDisplay = lambda candidate: display(candidate, startTime)fnGetFitness = lambda candidate: getFitness(candidate, rules)best = genetic.getBest(fnGetFitness, fnDisplay, len(one_neighbor_other), optimalValue, geneset)self.assertEqual(best.Fitness, optimalValue)keys = sorted(one_neighbor_other.keys())for index in range(len(one_neighbor_other)):print(keys[index]," is ",colorLookup[best.Genes[index]])# 输出各区域颜色def display(candidate, startTime):timeDiff = datetime.datetime.now() - startTimeprint("%s\t%i\t%s" % (''.join(map(str, candidate.Genes)), candidate.Fitness, str(timeDiff)))# 检查各区域颜色是否与个体基因所代表的颜色一致def getFitness(candidate, rules):rulesThatPass = 0for rule in rules:if candidate[rule.Item] != candidate[rule.Other]:rulesThatPass= 1return rulesThatPass# 运行程序GraphColoringTests().test()

2.3 结果展示

执行上述代码,即可得到结果。在这里值得一提的是:这个代码不知道是其自身原因,还是我电脑的问题,执行起来非常慢——单次运行时间可能在5 ~ 6个小时左右,实在太慢了;大家如果感兴趣,可以尝试着能不能将代码的效率提升一下。

代码执行完毕后得到的结果是文字形式的,具体如下图所示。

可以看到,通过203次迭代,找到了满足要求的地图配色方案,用时06小时06分钟;代码执行结果除显示出具体个体的整体基因型之外,还将分别显示78个小区域(小图斑)各自的具体颜色名称(我上面那幅图没有截全,实际上是78个小区域的颜色都会输出的)。

当然,大家也可以发现,这种文字表达的代码执行结果显然不如直接来一幅如下所示的结果图直观。但是,由于代码单次执行时间实在是太久了,我也没再腾出时间(其实是偷懒)对结果的可视化加以修改。大家如果感兴趣的话,可以尝试对代码最终的结果呈现部分加以修改——例如,可以通过Matplotlib库的拓展——Basemap库将78个小区域的配色方案进行可视化。

    推荐阅读
  • 2022年属虎人的运程(2022年属虎人的运程如何)

    2022年属虎人的运程?下面希望有你要的答案,我们一起来看看吧!属虎人的能力越强在这一年里就越要小心谨慎些,低估别人的实力容易吃亏,高估了自己的实力会出糗,稳定自己的情绪,保持平常心的状态去面对生活里发生的一切,这样才能够减少意外和麻烦的出现,也可以避开小人的纠缠。

  • 猕猴桃的营养价值(猕猴桃的营养价值是什么)

    猕猴桃的营养价值它含有亮氨酸、苯丙氨酸、异亮氨酸、酪氨酸、丙氨酸等十多种氨基酸,以及丰富的矿物质,包括丰富的钙、磷、铁,还含有胡萝卜素和多种维生素。猕猴桃对保持人体健康,防病治病具有重要的作用。多食用猕猴桃可以预防老年骨质疏松,抑制胆固醇的沉积,从而防治动脉硬化,还可改善心肌功能,防治心脏病等,也能对抗癌起到一点儿作用。多食用猕猴桃,还能阻止体内产生过多的过氧化物,防止老年斑的形成,延缓人体衰老。

  • 守护雷霆劫怎么玩(教你玩守护雷霆劫的简单方法)

    守护雷霆劫怎么玩阵容构成。2秘术,3召唤,2守护,4雷霆.看具体情况,若没有4雷霆,3雷霆也是可以的。掘墓,劫,奥恩,索拉卡,安妮,娜美,宝石,雷霆拉克丝。若没有雷霆拉克丝,可用狗熊换成3雷霆也很猛。前期需平稳过度,可用极地掠食或者森林德鲁伊等强势阵容,中期较为乏力,存钱利息升人口或变换中期强势阵容。

  • 气溶胶传播后能开窗吗(什么是气溶胶传播)

    通过流行病学调查显示,病例多可以追踪到与确诊的病例有过近距离密切接触的情况,这符合飞沫传播和接触传播的特征。但目前尚没有证据显示新型冠状病毒通过气溶胶传播。有的网友还问,空气中是否有新型冠状病毒?从这个角度讲,在日常通风环境下,空气中一般不会有新型冠状病毒。对于防护措施,一般的工作生活条件下,采取正确佩戴口罩这种飞沫传播防护措施,足以保护普通公众不被感染。

  • 燕窝简介(燕窝相关简介)

    燕窝简介燕窝是雨燕科几种金丝燕分泌的唾液及其绒羽混合粘结所筑成的巢穴。主产于马来西亚、印度尼西亚、泰国和缅甸等东南亚国家及我国的福建和广东沿海地带。燕窝中的主要营养成分是蛋白质,其中有1种必需氨基酸(赖氨酸),3种条件性必需氨基酸,而人体需要的必需氨基酸有8种,条件性必需氨基酸有13种。

  • 蛋奶球的做法(制作蛋奶球的方法详解)

    下面希望有你要的答案,我们一起来看看吧!蛋奶球的做法将除蔓越莓干以外的材料混合均匀放微波炉里加热2分钟,再加热一会儿。弄碎后再碾的细腻一点,取适量放在保鲜膜上。再放上一块,收起保鲜膜,手掐住封口。放在椰蓉里打个滚。做好了,香甜可口。

  • 一般高血压患者可以喝什么茶(高血压患者能喝茶吗)

    广州中医药大学第一附属医院心血管内科主任吴辉教授指出,茶叶中含有茶多酚,具有增强血管弹性的作用。它能降低血液中胆固醇、甘油三酯及低密度脂蛋白,还能降低胆固醇与磷脂的比例,从而达到了预防及治疗动脉硬化的目的。吴辉教授认为,绿茶和菊花茶同时饮用也可以起到辅助降压的效果。这样也可以起到降低血压,预防动脉硬化的作用。

  • 自然堂产品有假的吗(自然堂发布澄清声明)

    通告也指出,经生产(代理)企业所在地食品药品监管部门现场核查,伽蓝集团否认该产品为企业所生产(代理)。同时,也表明伽蓝集团将持续配合相关监管和执法部门加大打假力度,全力维护消费者合法权益。一直以来,伽蓝集团始终严格把控产品质量,遵守国家相关法律法规,目前官方授权销售的所有产品,消费者均可以放心使用。

  • 突围付长明和皮丹签合同(突围皮丹结局取代齐本安)

    因为这样,皮丹不能担负责任,别人行贿时,他会觉得这种事就是理所当然。这很大程度上,是因为程端阳的纵容。多年后,煤炭,矿业资源过剩,京州能源成为公司的负增长企业。齐本安在京州的一番作为,惹怒了很多人,更重要的是惹怒了林满江,动了林满江的蛋糕,让林满江对他产生严重的不满。

  • 包价旅游和旅游包价的区别(看完这篇你就明白了)

    旅游包价在全包价基础上,扣除午、晚餐费用的包价形式,其目的在于降低产品的直观价格,提高产品的竞争能力,同时也可更好地满足游客在用餐方面的要求,两者区别一目了然。包价旅游是指旅游者在旅游活动中开始前即将全部或部分旅游费用预付给旅行社,由旅行社根据同旅游者签订的合同,相应地为旅游者安排旅游途中的吃、住、行、游、购、娱等活动。