Python 遗传算法 Genetic Algorithm

article/2025/10/2 0:04:52

粒子群算法常常用于在连续解空间内搜索,而在不连续、离散的空间内常常会出现搜索越界的问题

例如旅行商问题,寻找可以遍历 15 个地点的最短路径(当然可以用二进制状态压缩 + 动态规划解决),以 {0, 1, ..., 14} 表示这些地点,并以 {0, 1, ..., 14} 的一种排列方式为一个解

当这个问题的解集映射在 15 维空间中时,这个空间中的可行解将非常的稀疏,从而阻碍粒子群的搜索

遗传算法有几个关键词:

  • 保优:当种群更新时,不改变最优的几个个体,为交叉提供优质基因并与新个体进行比较
  • 天择:根据每个个体的适应度,使用轮盘赌法进行挑选
  • 交叉:对天择生成的每个个体,以一定概率与原来的个体进行交叉
  • 变异:对天择生成的每个个体,以一定概率进行基因突变

下面是我编写的遗传算法模板,在使用时需要重写 new_unit(群体初始化方法)、cross(两个体交叉方法)、variation(个体变异方法)、fitness(个体适应度计算方法) 函数(后面我将会以旅行商问题进行举例)

其中的 fit 方法为主函数,记群体规模为 n,for 循环体的内容为:

  • 对当前的群体进行重叠检测,去除重复的个体
  • 计算每个个体的适应度,排序后对适应度前 5% 的个体进行“保优”,得到规模 0.05n 的新群体
  • 对原有群体进行天择,选出 0.95n 的个体(可重复),根据概率对每个个体进行交叉、变异操作,加入新群体得到规模 n 的群体
import numpy as np
from tqdm import trangeDTYPE = np.float16class Genetic_Algorithm:''' 遗传算法n_unit: 染色体群体规模n_gene: 染色体的基因数well_radio: 最优个体比例cross_proba: 交叉概率var_proba: 变异概率'''def __init__(self,n_unit: int,n_gene: int,well_radio: float = 0.05,cross_proba: float = 0.4,var_proba: float = 0.3):self._n_unit = n_unitself._n_gene = n_geneself._well_radio = well_radioself._cross_proba = cross_probaself._var_proba = var_probaself.group = self.new_unit(self._n_unit)def _random_section(self) -> tuple:''' 产生随机区间'''gene_idx = list(range(self._n_gene))l = np.random.choice(gene_idx)r = np.random.choice(gene_idx[l:])return l, rdef new_unit(self, size) -> np.ndarray:''' 初始化染色体群体return: [size, n_gene]'''raise NotImplementedErrordef cross(self, unit, other) -> np.ndarray:''' 交叉遗传return: [n_gene, ]'''raise NotImplementedErrordef variation(self, unit) -> np.ndarray:''' 基因突变return: [n_gene, ]'''l, r = self._random_section()np.random.shuffle(unit[l: r + 1])return unitdef fitness(self, unit) -> float:''' 适应度函数 (max -> best)'''raise NotImplementedErrordef fit(self, epochs: int,patience: int = np.inf,prefix='GA_fit') -> np.ndarray:''' epochs: 训练轮次patience: 允许搜索无进展的次数'''unit_idx = list(range(self._n_unit))pbar = trange(epochs)last_fitness, angry = - np.inf, 0# 最优个体数, 随机选取数n_well = round(self._n_unit * self._well_radio)n_choose = self._n_unit - n_wellfor _ in pbar:self.group = np.unique(self.group, axis=0)# 计算每个个体的适应度并排序fitness = np.array(list(map(self.fitness, self.group)), dtype=DTYPE)order = np.argsort(fitness)[::-1]# 收敛检测cur_fitness = fitness[order[0]]angry = 0 if cur_fitness > last_fitness else angry + 1last_fitness = cur_fitnessif angry == patience: break# 保留一定数量的个体new_group = self.group[order[:n_well]]pbar.set_description((f'%-10s' + '%-10.4g') % (prefix, cur_fitness))fitness -= fitness.min()# 根据适应度, 使用轮盘赌法进行筛选proba = fitness / fitness.sum()choose_idx = np.random.choice(unit_idx[:len(self.group)], size=n_choose, p=proba)# 交叉遗传 / 基因突变for unit, (pc, pv) in zip(self.group[choose_idx], np.random.random([n_choose, 2])):if pc <= self._cross_proba:unit = self.cross(unit, self.group[np.random.choice(unit_idx[:len(self.group)], p=proba)])if pv <= self._var_proba:unit = self.variation(unit)# 拼接新个体new_group = np.concatenate([new_group, unit[None]])self.group = new_groupreturn self.group[0]

求解示例

对于 15 个地点的旅行商问题,重写的函数思路如下:

  • new_unit:生成 n 个 [0, 1, ..., 14],使用 np.random.shuffle 进行打乱
  • fitness_cal:使用实例属性 pos 记录 15 个地点的位置,实例属性 adj 记录这 15 个地点的邻接矩阵;依次遍历个体中的地点叠加距离(越小表示该解越优),并取负值(越大表示该解越优,符合 fit 函数的设计)
  • cross:因为旅行商问题中的解在进行交叉时(交换片段),容易出现“重复经过一地点”的情况,故此处不使用交叉
  • variation:随机选取区间的左右边界,使用 np.random.shuffle 对该区间的基因进行打乱(已编写在模板中)
if __name__ == '__main__':import matplotlib.pyplot as pltclass Shortest_Path(Genetic_Algorithm):def new_unit(self, size):''' 初始化染色体群体'''group = []for _ in range(size):unit = list(range(self._n_gene))np.random.shuffle(unit)group += [unit]return np.array(group, dtype=np.int32)def fitness(self, unit):''' 适应度函数 (max -> best)'''# 初始化邻接表if not hasattr(self, 'adj'):self.pos = np.random.random([self._n_gene, 2]) * 10self.adj = np.zeros([self._n_gene] * 2, dtype=DTYPE)for i in range(self._n_gene):for j in range(i + 1, self._n_gene):self.adj[i][j] = self.adj[j][i] = \np.sqrt(((self.pos[i] - self.pos[j]) ** 2).sum())# 计算适应度fitness = 0for i in range(self._n_gene - 1):dist = self.adj[unit[i]][unit[i + 1]]fitness += distreturn - fitnessnp.random.seed(0)ga = Shortest_Path(80, 15, cross_proba=0, var_proba=0.6)unit = ga.fit(500)# 绘制最优路径fig = plt.subplot()for key in 'right', 'top':fig.spines[key].set_color('None')plt.plot(*ga.pos[unit].T, c='deepskyblue')plt.scatter(*ga.pos.T, marker='p', c='orange')plt.show()


http://chatgpt.dhexx.cn/article/FBnKhoup.shtml

相关文章

python遗传算法之geatpy学习

&#x1f63b;今天我们来学习python中的遗传算法的使用&#xff0c;我们这里使用的是geatpy的包进行学习&#xff0c;本博客主要从geatpy中的各种数据结构一步一步进行学习&#xff0c;请大家耐心看完。 &#x1f424;其实以前也学习过遗传算法&#xff0c;但是主要使用matlab…

遗传算法详解 附python代码实现

遗传算法 遗传算法是用于解决最优化问题的一种搜索算法。从名字来看&#xff0c;遗传算法借用了生物学里达尔文的进化理论&#xff1a;”适者生存&#xff0c;不适者淘汰“&#xff0c;将该理论以算法的形式表现出来就是遗传算法的过程。 问题引入 上面提到遗传算法是用来解…

遗传算法【Python】

遗传算法概念 基本思想&#xff1a; 遗传算法(GA)是一种全局寻优搜索算法&#xff0c;它依据的是大自然生物进化过程中“适者生存”的规律。它首先对问题的可行解进行编码&#xff0c;组成染色体&#xff0c;然后通过模拟自然界的进化过程&#xff0c;对初始种群中的染色体进…

遗传算法python实现

遗传算法python实现 一、问题引入二、遗传算法的步骤1.初始化2.个体评价3.选择运算4.交叉运算5.变异运算6.终止条件判断 三、实现思路1.编码的设计2.适应度函数3.选择函数4.交叉函数5.变异函数6.迭代 四、具体实现1.编码解码函数2.适应度函数3.选择函数4.交叉函数5.变异函数6.选…

遗传算法(Python)

一、遗传算法 1、遗传算法的定义 遗传算法是一种现代优化算法。根据自然界适者生存的法则&#xff0c;种群中优秀个体的基因进行遗传。每个个体的染色体通过选择、交叉和变异等过程产生新的适应度更大的染色体&#xff0c;其中适应度越大的个体越优秀&#xff0c;种群得到优化…

python遗传算法(详解)

学习代码来源于&#xff1a;遗传算法python 一.主要思想 遗传算法是根据达尔文的“适者生存&#xff0c;优胜劣汰”的思想来找到最优解的额&#xff0c;其特点是所找到的解是全局最优解&#xff0c;相对于蚁群算法可能出现的局部最优解还是有优势的。 二.主要名词 个体&…

DH算法、DHE算法、ECDHE算法演进

ECDHE 算法解决了 RSA 算法不具备前向安全的性质 和 DH 算法效率低下的问题。 ECDHE 算法具有前向安全。所以被广泛使用。 由什么演变而来 DH 算法 -- > DHE 算法 -- > ECDHE 算法 DH 算法是非对称加密算法&#xff0c;该算法的核心数学思想是离散对数。 核心数学思…

DH 算法思想 SSH解决内容篡改问题

DH算法用于交换密钥 交换密钥的目的是生成仅双方共享的密钥 交换密钥的基本过程&#xff1a; 双方确定公开的内容用各自的私钥分别对公共内容加密&#xff08;加密本质就是数学运算&#xff09;并发送给对方这时双方使用自己的密钥对收到的内容加密&#xff08;要设计运算保证…

ECDH算法详解

ECDH算法详解 ECDH算法详解DH密钥交换原理结合ECC椭圆曲线算法ECDSA签名算法 参考资料 ECDH算法详解 DH密钥交换原理 进一步解释&#xff1a; 两端&#xff08;Alice 和 Bob&#xff09;想要安全的交换信息并且第三方不能获取到该信息。当然这也是TLS协议中的目的之一&#xf…

DH算法(密钥交换算法)

一 对称加密缺点 密钥传递过程复杂&#xff0c;这是对称加密带来的困扰。 二 DH密钥交换算法特点 构建本地密钥 双方密钥一致 三 DH相关参数 四 DH算法实现过程 1、初始化发送方的密钥&#xff08;KeyPairGenerator、KeyPair、PublicKey&#xff09; 2、初始化接受方的密钥&…

SSL/TLS中的DH算法、DHE算法、 ECDHE算法介绍

❤️SSL/TLS专栏导航页❤️ 文章目录 1. DH算法简介2. DH算法协商流程3. DH算法证明4. SSL/TLS中的DH算法 1. DH算法简介 Diffie-Hellman密钥交换算法是在1976年由这两个人发明的算法。它可以在不安全的网络中&#xff0c;通过交换一些公开的信息协商出共享密钥&#xff0c;使…

一文读懂DH密钥交换算法

DH 算法是 Diffie和Hellman于1976年提出了一种的密钥交换协议。这种加密算法主要用于密钥的交换&#xff0c;可以在非安全信道下为双方创建通信密钥&#xff0c;通讯双方可以使用这个密钥进行消息的加密、解密&#xff0c;并且能够保证通讯的安全。 换而言之&#xff0c;算法希…

密钥协商算法的演变 —— RSA算法 - DH算法 - DHE算法 - ECDHE算法

文章目录 1. RSA算法RSA握手过程RSA秘钥协商算法最大的缺陷 2. DH算法3. DHE算法4. ECDHE算法ECDHE秘钥协商算法的TSL握手&#xff1a; 1. RSA算法 传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的。在 RSA 密钥协商算法中&#xff0c;客户端会⽣成随机密钥&#xff0c…

openswan中DH算法说明

Author :Email : vip_13031075266163.comDate : 2021.01.11Copyright : 未经同意不得转载&#xff01;&#xff01;&#xff01;Version &#xff1a; openswan-2.6.51.5Reference&#xff1a;https://download.openswan.org/openswan/ 目录 1. ope…

DH法理解

旋转关节机器人 四个参数&#xff1a;a&#xff0c;α&#xff0c;d&#xff0c;θ 四个参数实际上是两组&#xff0c;先有a&#xff0c;α&#xff0c;再有d&#xff0c;θ。 a是两个转轴之间的距离&#xff08;Z轴&#xff09;&#xff0c;异面直线公垂线的长度&#xff0c;也…

DH算法及源码解读

【主流的密钥交换方式】 敏感数据信息安全传输需要对敏感信息加密&#xff0c;加密的密钥涉及到传输两端的密钥协商和交换&#xff0c;目前主要两种密钥交换的机制有&#xff1a; 1. 基于非对称密钥的实现&#xff1a;请求方用接收方的公钥加密自己的密钥&#xff0c;接收方用…

DH 加密算法的使用

DH 算法的介绍 上面介绍的 DES,3DES,AES 算法都是对称密码算法&#xff0c;所谓对称&#xff0c;在上面也解释了&#xff0c;就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法&#xff0c;属于非对称密码算法&#xff0c;根据对称密码的概念&#xff0c;很…

非对称加密 DH算法

DH算法简介 迪菲-赫尔曼密钥交换&#xff08;Diffie–Hellman key exchange&#xff0c;缩写为D-H&#xff09; 是一种安全协议。 它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。 迪…

DH算法 | Diffie-Hellman 密钥交换

概述&#xff1a; DH 算法又称“Diffie–Hellman 算法”&#xff0c;像往常的算法名字一样&#xff0c;这是用俩个数学牛人的名字来命名的算法&#xff0c;实现安全的密钥交换&#xff0c;通讯双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 优点&am…

DH算法原理

DH算法原理 DH 是 Diffie-Hellman的首字母缩写&#xff0c;是Whitefield与Martin Hellman在1976年提出了一个的密钥交换协议。我个人倾向于称DH算法为 密钥协商协议而RSA算法是密钥交换算法。 本篇分为几个部分&#xff0c;第一个部分介绍一下密钥交换的场景&#xff1b;第二部…