Python:遗传算法最优路径

news2024/9/27 9:21:49

Hello,大家好!读研前写过一篇遗传算法的代码,比较简单,算是个入门,当时就有想用它来解决最优路径的问题,上算法导论课时碰巧有听到同学有分享过,但由于自己研究的方向不是这块,就没有再弄,结果今年的华为杯数学建模竞赛F题居然有所涉及,真是用时方恨晚,最近即将毕业,也稍微空闲些了,就再用遗传算法慢慢捡回我的公众号。今天分享的是如何用遗传算法进行最优路径求解问题!

用python实现遗传算法这是两年前写的遗传算法,做了一个简单的介绍,感兴趣的小伙伴可以翻看。

目录

  • 问题
  • 思路与Python实现
    • 编码
    • 个体评价
    • 选择
    • 交叉
    • 变异
    • 整合
    • 效果演示
  • 获得代码

问题

现在有 n n n个地址的坐标,以第一个为起点,途径所有地址,再回到起点,所有地方仅去一次,规划最短路径。

思路与Python实现

编码

首先先解决编码问题,与上篇文章不同,这次解决的是路径规划问题,有的是一个一个的坐标点,因此我们采用“符号编码”代表这些坐标点,染色体上的编码顺序代表路径顺序。

我们随机生成十组坐标,用作本文的示范:

a = list(range(-5,5))
b = list(range(-4,6))
random.shuffle(a)
random.shuffle(b)
local = list(zip(a,b))
序号横坐标纵坐标
0-5-2
1-34
245
3-4-3
4-11
50-1
613
72-4
8-20
932

这些序号就可以用作我们符号编码,例如[0,1,2,3,4,5,6,7,8,9]

个体评价

个体评价也就是我们的目标函数,用来区分群体中个体好坏的标准。我们路径规划问题是寻找最短行驶路径,这里用两点之间距离公式进行度量,然后按照染色体上的编码顺序依次累加两点之间的距离:

def dis(start, end):
    # 两点之间距离
    return np.sqrt((end[0]-start[0])**2+(end[1]-start[1])**2)

def fuc(x):
    dis_sum = dis((0,0),local[x[0]])
    for i in range(1,len(x)):
        dis_sum += dis(local[x[i-1]],local[x[i]])
    dis_sum += dis(local[x[-1]],(0,0))
    return dis_sum

def get_fitness(pops):
    return list(map(fuc,pops))

注:本文是以原点作为线路的起点和终点,形成闭环,不同情况要不同设计

选择

选择算子的作用是对个体进行优胜劣汰:从父代群体中选取一些适应度高个体遗传到下一代群体中,这次采用锦标赛选择策略

锦标赛选择策略:从种群中随机采样 s s s个个体(有放回抽样)进行PK,其中适应度值最优的个体胜出,成为下一代的父代基因,进行 k k k轮,得到 k k k个优质父代。

这样最差的个体永远不会存活,并且计算简单,不容易陷入局部最优,可以达到更好的求解效果。

def select(pops):
    k = round(np.sqrt(len(pops)+0.25)+0.5)
    fitness = get_fitness(pops)
    father_pops = []
    for i in range(k):
        min_index = np.array(fitness).argmin()
        father_pops.append(pops.pop(min_index))
        fitness.pop(min_index)
    return father_pops

交叉

接下来就到了整个算法的重头,不同于上一篇文章,单纯地使用两点交叉即可,路径规划中,所有的地点要秉持“不遗漏,不重复”的原则,如果单纯地交叉,会导致地点重复或遗漏。因此就在两点交叉的过程中加一个映射过程,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rTQ4O7x8-1671273828116)(.\figures\两点交叉策略示例.png)]

def yinshe(dic, x): # 映射
    while x in dic.keys():
        x = dic[x]
    return x

def jiaocha(Lis1, Lis2): # 两点交叉
    lis1 = Lis1.copy()
    lis2 = Lis2.copy()
    n = len(lis1)
    cross_points_1 = np.random.randint(low=0, high=n-1)
    cross_points_2 = np.random.randint(low=cross_points_1+1, high=n)
    
    yinshe2 = dict(zip(lis1[cross_points_1: cross_points_2],lis2[cross_points_1: cross_points_2]))
    yinshe1 = dict(zip(lis2[cross_points_1: cross_points_2],lis1[cross_points_1: cross_points_2]))

    lis1[cross_points_1: cross_points_2], lis2[cross_points_1: cross_points_2] = lis2[cross_points_1: cross_points_2], lis1[cross_points_1: cross_points_2]
    
    lis1[:cross_points_1] = list(map(lambda x: yinshe(yinshe1, x), lis1[:cross_points_1]))
    lis1[cross_points_2:] = list(map(lambda x: yinshe(yinshe1, x), lis1[cross_points_2:]))
    lis2[:cross_points_1] = list(map(lambda x: yinshe(yinshe2, x), lis2[:cross_points_1]))
    lis2[cross_points_2:] = list(map(lambda x: yinshe(yinshe2, x), lis2[cross_points_2:]))
    return lis1, lis2

细心的小伙伴肯定就发现了,为什么映射过程的代码里有一个while循环,这个地方是我在实验的过程中发现的一个细节,如果单靠一次映射,并不能保证所重复的点都映射完,就像上图中的例子,明明 9 9 9对应的是 4 4 4,但是 4 4 4本身也在交叉的基因之中,并没能把9映射到外面,故需要三次映射,即 9 → 4 → 3 → 6 9 \rightarrow 4 \rightarrow 3 \rightarrow 6 9436,因此才把外面的 9 9 9替换为了 6 6 6

变异

是对群体中的个体的某些基因座上的基因值作变动,模拟生物在繁殖过程,新产生的染色体中的基因会以一定的概率发生突变。这样的设计可以很好地避免局部最优的情况。

def mutation(pop, MUTATION_RATE=0.003):
    if np.random.rand() < MUTATION_RATE:
        n = len(pop)
        cross_points_1 = np.random.randint(low=0, high=n-1)
        cross_points_2 = np.random.randint(low=cross_points_1+1, high=n)
        pop[cross_points_1], pop[cross_points_2] = pop[cross_points_2], pop[cross_points_1]
    return pop

整合

有了“个体评价”、“选择”、“交叉”、“变异”这些模块,就可以实现一代代的遗传进化:

def evolution(pops):
    father_pops = select(pops)
    k = len(father_pops)
    new_pops = []
    for i in range(k-1):
        for j in range(i+1,k):
            son1, son2 = jiaocha(father_pops[i], father_pops[j])
            son1 = mutation(son1, MUTATION_RATE=0.3)
            son2 = mutation(son2, MUTATION_RATE=0.3)
            new_pops.append(son1)
            new_pops.append(son2)
    return new_pops

效果演示

最后只需要把前面的内容整合在一起即可,因为问题比较简单,所以遗传的代数设置50就足够了。

local = [(-5, -2), (-3, 4), (4, 5), (-4, -3), (-1, 1), (0, -1), (1, 3), (2, -4), (-2, 0), (3, 2)]
pops = initpop(N, list(range(10)))
for _ in range(50):
    pops = evolution(pops)
print(min(get_fitness(pops)))

然后我们把整个遗传过程可视化出来,效果如所想的一样,最短的路径就是围着转一圈,整个过程感觉还是非常神奇的,如果有想要这个可视化代码的小伙伴,可在文末获得,文章中就不再赘述了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8ikJ09L-1671273828118)(.\figures\演示.gif)]

获得代码

以下是我的个人公众号,本文完整代码已上传,关注公众号回复“遗传算法最优路径”,即可获得,谢谢大家支持。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sX4ltMkB-1671273828118)(F:\公众号\0.jpg)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode每日一题】——968.监控二叉树

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 树 二【题目难度】 困难 三【题目编号】 968.监控二叉树 四【题目描述】 给定一个二叉树&…

入门:从虚拟机到容器

从虚拟机到容器 前面我们成功安装了Docker学习环境&#xff0c;以及浅尝了一下Docker为我们带来的应用快速部署。在正式进入学习之前&#xff0c;我们就先从Docker的发展开始说起。 在Docker出现之前&#xff0c;虚拟化技术可以说是占据了主导地位。首先我们来谈谈为什么会出现…

Adobe Pro DC 2022 软件详细安装教程

一、软件下载 网盘链接&#xff1a;Adobe Pro DC 2022 提取码:ib19 二、详细安装教程 1、解压安装包&#xff0c;右键安装程序Set-up&#xff0c;点击以管理员身份运行 2、更改软件安装位置&#xff0c;建议安装至除C盘外的其他盘&#xff08;如不需更改直接点击【继续】即可…

自学编程的朋友,我想给你们这 5 个建议

0基础学编程&#xff0c;我想给你这 5 个建议 很多人都想转行互联网&#xff0c;不管是出于兴趣、行业前景还是薪资的考虑&#xff0c;想要转行互联网的人们必须要面对一个问题&#xff0c;那就是如何自学编程&#xff0c;更确切的说&#xff0c;是如何0基础学编程。 其实我基…

小师弟:2022广东省工科赛分享(越障排爆省一,完整项目)

目录日常唠嗑前言一、实验效果二、赛题分析及方案1、赛题内容&#xff1a;初赛&#xff1a;决赛&#xff1a;2、实施方案&#xff1a;三、材料选择四、程序设计程序思路PID&#xff1a;越障部分&#xff1a;颜色识别部分&#xff1a;五、竞赛心得六、工程获取日常唠嗑 小师弟说…

J-002 Jetson电路设计之电源设计--NANO XAVIER NX

Jetson电源设计1 电源说明1.1 电源和系统引脚描述1.2 电源控制框图详情2 上电的时许2.1 框图分析2.2 上电时序3 GND引脚1 电源说明 Jetson NANO和XAVIER NX核心板的电源为DC-5V。 1.1 电源和系统引脚描述 PIN名称描述方向类型251-260VDD_IN主电源输入5.0V235PMIC_BBATRTC时钟…

深入剖析Linux RCU原理(二)-渐入佳境

说明&#xff1a; Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 概述 我会假设你已经看过了深入剖析Linux RCU原理&#xff08;一&#xff09;初窥门径 本文将进一步去探索下…

设计模式4 - 行为型模式

23种设计模式分析与见解开篇、UML、软件设计原则https://blog.csdn.net/lili40342/article/details/128358435创建型模式https://blog.csdn.net/lili40342/article/details/128358392结构型模式https://blog.csdn.net/lili40342/article/details/128358313行为型模式https://bl…

【GRU时序预测】基于matlab卷积神经网络结合门控循环单元CNN-GRU时间序列预测【含Matlab源码 2287期】

⛄一、CNN-GRU数据预测 1 理论基础 1.1 CNN算法 负荷序列数据为一维数据&#xff0c;用一维卷积核对数据进行卷积处理&#xff0c;以获取数据的特征。 现设定卷积核的维度为3&#xff0c;移动步长为1&#xff0c;对输入数据进行卷积&#xff0c;以获得特征图图谱&#xff0c;即…

转行AI产品经理的学习过程

学习内容及思考 引言 当别人问你为什么转行AI产品经理&#xff1f; 你回答因为自己喜欢。 这是一句多么空洞的话呀&#xff0c;苍白又无力&#xff0c;那你为什么喜欢呢&#xff1f;你了解他么&#xff1f;仅凭自己这一腔热情&#xff0c;一句轻描淡写的我喜欢&#xff0c;是…

行为树 --- [7] BehaviorTree.CPP 4.x版本的编译及使用

根据BehaviorTree.CPP的官方介绍&#xff0c;3.x版本已经不再维护了&#xff0c;建议使用4.x版本&#xff0c; 4.x版本和3.x版本的区别可以看这里 — https://www.behaviortree.dev/migration 本文介绍4.x版本的编译及使用&#xff0c;环境是Debian 10.5&#xff0c;编译器是…

笔试强训(四十七)

目录一、选择题二、编程题2.1 合唱团2.1.1 题目2.1.2 题解2.2 马戏团2.2.1 题目2.2.2 题解一、选择题 &#xff08;1&#xff09;对于IP地址130.63.160.2&#xff0c;MASK为255.255.255.0&#xff0c;子网号为&#xff08;B&#xff09; A.160.2 B.160 C.63.160 D.130.63.160 …

学Python好找工作吗?需要满足Python岗位哪些要求?

学Python好找工作吗&#xff1f;需要满足哪些要求&#xff1f;随着Python的火爆&#xff0c;国内Python的岗位也随之增多&#xff0c;只要技术能力强项目经验充足&#xff0c;找到工作不是问题。即使是一些二线城市&#xff0c;Python的薪资待遇也比较好。 一、学Python好找工作…

学习编程的中小学生越来越多,是盲目追风,还是确有其用?!

首先&#xff0c;中小学生为什么要学习编程?未来社会&#xff0c;随姜信息技术和人工智能的发展&#xff0c;越来越多行业的工作离不开编程。美国前总统奥巴马就呼吁:“如果我们想让美国保持地位&#xff0c;就需要年轻代的美国人掌握这种(编程)工具和技术,它将改变我们所有的…

最简单的canvas基础+实践,确定不进来看看嘛

前言 怎么突然提到 canvas 呢❓其实是因为工作中有一个小需求&#xff0c;就是给特定的区域做水印&#x1f624;&#xff0c;思来想去&#x1f60e;就选择使用 canvas 去做&#xff0c;简单效果如下&#xff1a; 实现思路&#x1f937;‍♂️&#xff1a;封装一个全局指令&am…

新装的Ubuntu无法连接有线(无有线标志)

解决方法 1、lspci命令&#xff08;查看网卡型号&#xff09; labhlab:~$ lspci 00:00.0 Host bridge: Intel Corporation Device 4660 (rev 02) 00:01.0 PCI bridge: Intel Corporation Device 460d (rev 02) 00:06.0 PCI bridge: Intel Corporation Device 464d (rev 02) 0…

【图像增强】局部对比度增强的CLAHE算法直方图增强【含Matlab源码 1341期】

⛄一、简介 基于matlab局部对比度增强的CLAHE算法直方图增强 ⛄二、部分源代码 %% tic %% 清空工作区与变量 clc; clear; for image_number1:1 imageNamestrcat(num2str(image_number),‘.jpg’); img imread(imageName); %% 在LAB空间进行去雾 % RGB转LAB transform mak…

【数据结构】堆(一)——堆的实现

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 堆的概念及结构&#xff1a; 堆的实现思路&#xff1a;&#xff08;我…

【教学类-23-01】20221217《不会写学号的中班幼儿的学号描字贴》(中班描字)

成品样式&#xff1a; 每个孩子3页A4横板&#xff0c;供6次书写 打印样式&#xff1a; 背景需求&#xff1a; 前期进行6次的Python学具教学活动&#xff0c;对中3班幼儿书写学号和名字的情况评估&#xff1a; 筛选出10位需要练习学号的幼儿。 学号、名字需要持续性、强化性练…

科技改变世界,科技改变世界杯

2022年11月20日&#xff0c;2022年卡塔尔世界杯&#xff08;英语&#xff1a;FIFA World Cup Qatar 2022&#xff09;在充满阿拉伯风情的开幕式中拉开了帷幕。 相比以往世界杯&#xff0c;今年卡塔尔世界杯在赛场上加设的黑科技&#xff0c;让我们在赛场上反复领略到了各种剧情…