数学建模学习(1)遗传算法

一、简介

        遗传算法(Genetic Algorithm, GA)是一种用于解决优化搜索问题的进化算法。它基于自然选择和遗传学原理,通过模拟生物进化过程来寻找最优解。

        以下是遗传算法的主要步骤和概念:

  • 初始化种群(Initialization):随机生成一组可能的解(个体),形成初始种群。

  • 适应度评估(Fitness Evaluation):根据适应度函数评估每个个体的质量,即其解问题的效果。

  • 选择(Selection):根据适应度选择较优的个体进行繁殖。常见的选择方法包括轮盘赌选择锦标赛选择排序选择

  • 交叉(Crossover):将两个个体的部分基因组合生成新的个体(子代)。交叉操作模拟生物的基因重组,常见的交叉方法有单点交叉和多点交叉。

  • 变异(Mutation):随机改变个体的部分基因,以增加种群的多样性,防止算法陷入局部最优。变异操作模拟生物的基因突变。

  • 替换(Replacement):将子代个体加入种群中,通常会替换掉适应度较低的个体,以保持种群规模恒定。

  • 终止条件(Termination Condition):当达到预定的终止条件时(如运行一定代数、适应度达到某个阈值),算法停止,输出最优解。

        遗传算法通常用于解决以下类型的问题:

  • 优化问题,例如函数优化、路径优化(如旅行商问题)。
  • 搜索问题,例如求解数独、密码破解。
  • 机器学习中的参数优化,例如神经网络权重优化。

优点

  • 遗传算法具有全局搜索能力,能够在较大的搜索空间中找到全局最优解。
  • 适用于复杂的、多维的、非线性的优化问题。
  • 不依赖于问题的具体数学性质,可以处理各种类型的目标函数和约束条件。

缺点

  • 计算代价较高,尤其是适应度评估过程可能耗时。
  • 需要精心设计适应度函数、选择方法、交叉和变异操作,才能获得好的效果。
  • 对于某些问题,可能会收敛到局部最优解,而非全局最优解。

二、算法介绍 

(1)适应度函数

(2)轮盘赌选择

(3)锦标赛选择

(4)排序选择

 

(5)单点交叉 

应用场景

        单点交叉适用于问题规模较小或基因序列较短的情况。

        对于复杂问题或基因序列较长的情况,可以考虑多点交叉均匀交叉等更复杂的交叉方法,以提高解的多样性和质量。

(6) 多点交叉

(7)均匀交叉 

 

 

(8)变异 

        通常设置较低的变异率(如 0.1% 到 1%)

三、遗传算法解TSP 

import copy
import random
import math
import numpy as np
import matplotlib.pyplot as pltN = 20000  # 最大迭代次数
city_num = 31
pop_size = 100  # 种群数量
pc = 0.8  # 交叉概率
pm = 0.05  # 变异概率# 城市坐标
city_position = [(1304, 2312), (3639, 1315), (4177, 2244), (3712, 1399), (3488, 1535),(3326, 1556), (3238, 1229), (4196, 1004), (4312, 790), (4380, 570),(3007, 1970), (2562, 1756), (2788, 1491), (2381, 1676), (1332, 695),(3715, 1678), (3918, 2179), (4061, 2370), (3780, 2212), (3676, 2578),(4029, 2838), (4263, 2931), (3429, 1908), (3507, 2367), (3394, 2643),(3439, 3201), (2935, 3240), (3140, 3550), (2545, 2357), (2778, 2826), (2370, 2975)]# 距离矩阵,城市之间的距离
dis = np.zeros((31, 31))
for i in range(31):for j in range(31):if i != j:dis[i][j] = ((city_position[i][0] - city_position[j][0]) ** 2 + (city_position[i][1] - city_position[j][1]) ** 2) ** 0.5# 初始化种群并去重
def init(pop_size, city_num):population = []while len(population) < pop_size:temp = random.sample(range(city_num), city_num)if temp not in population:population.append((temp))return population# 适应度函数
def fitness(population, dis):fitness = []for i in range(len(population)):distance = 0for j in range(city_num - 1):distance += dis[population[i][j]][population[i][j + 1]]distance += dis[population[i][-1]][population[i][0]]if distance == 0:f = float('inf')else:f = 1 / (distance ** 2)fitness.append(f)return fitness# 选择函数:轮盘赌选择
def select(population, fitness):index = random.randint(0, pop_size - 1)num = 0r = random.uniform(0, sum(fitness))for i in range(len(population)):num += fitness[i]if num >= r:index = ibreakreturn population[index]# 交叉函数
def cross(fa1, fa2):if random.random() < pc:chrom1 = fa1[:]chrom2 = fa2[:]cpoint1 = random.randint(0, city_num - 1)cpoint2 = random.randint(0, city_num - 1)if cpoint1 > cpoint2:temp = cpoint1cpoint1 = cpoint2cpoint2 = temptemp1 = []temp2 = []for i in range(cpoint1, len(chrom1)):temp1.append(chrom1[i])temp2.append(chrom2[i])for i in range(cpoint1, cpoint2 + 1):chrom1[i] = fa2[i]chrom2[i] = fa1[i]new_chrom1 = []new_chrom2 = []for i in range(cpoint2 + 1):new_chrom1.append(chrom1[i])new_chrom2.append(chrom2[i])new_chrom1.extend(temp1)new_chrom2.extend(temp2)ans1 = []ans2 = []for i in range(len(new_chrom1)):if new_chrom1[i] not in ans1:ans1.append(new_chrom1[i])for i in range(len(new_chrom2)):if new_chrom2[i] not in ans2:ans2.append(new_chrom2[i])return ans1, ans2else:return fa1[:], fa2[:]# 变异函数
def mutate(chrom):if random.random() < pm:mpoint1 = random.randint(0, city_num - 1)mpoint2 = random.randint(0, city_num - 1)temp = chrom[mpoint1]chrom[mpoint1] = chrom[mpoint2]chrom[mpoint2] = tempreturn chromdef show(lx, ly, fit_history):# 画出每代最好适应值的图像plt.plot(range(len(fit_history)), fit_history)plt.xlabel("Generation")plt.ylabel("Fitness")plt.show()# 画出最短路径大小的变化图a = []for i in range(len(fit_history)):a.append(math.sqrt(1 / fit_history[i]))plt.plot(range(len(a)), a)plt.xlabel("Generation")plt.ylabel("Best_path_size")plt.show()def best_show(x, y, Best_Fitness):# 定义两个子图fig, ax = plt.subplots(1, 2, figsize=(12, 5), facecolor='#ccddef')# 定义子图1标题ax[0].set_title("Best route")# 定义子图2标题ax[1].set_title("Best_Fitness Change Procession")# 画线ax[0].plot(x, y)# 画点(第一个子图)ax[0].scatter(x, y, color='r')# 画线(第二个子图)ax[1].plot(range(len(Best_Fitness)), [Best_Fitness[i] for i in range(len(Best_Fitness))])plt.show()# 主程序
if __name__ == '__main__':best_fit = 0.0ans = []best_path = []population = init(pop_size, city_num)  # 初始化种群,pop_size:种群个数for i in range(N):fit = fitness(population, dis)  # 计算适应度列表max_fit = max(fit)  # 因为适应度是采用距离和的平方的倒数,故最大的适应度代表距离最小max_index = fit.index(max_fit)  # 最大适应度的方案索引lx = []ly = []for j in population[max_index][:]:j = int(j)  # 保证整数lx.append(city_position[j][0])ly.append(city_position[j][1])if max_fit > best_fit:  # 假如路径更短best_fit = max_fit  # 修正了这里的错别字ans = population[max_index][:]x = copy.copy(lx)y = copy.copy(ly)best_path.append(best_fit)  # 记录适应度变化,为画图准备# 变异、交叉new_population = []n = 0while n < pop_size:p1 = select(population, fit)p2 = select(population, fit)while p2 == p1:p2 = select(population, fit)# 交叉chrom1, chrom2 = cross(p1, p2)# 变异chrom1 = mutate(chrom1)chrom2 = mutate(chrom2)new_population.append(chrom1)new_population.append(chrom2)n += 2population = new_populationprint("######################################################")print(f"第{i + 1}代的最优路径为:", ans)print("最短路径为:", (1 / best_fit) ** 0.5)show(lx,ly,best_path)x.append(x[0])y.append(y[0])best_show(x,y,best_path)

结果:

 

 

对比模拟退火算法的结果:

(以下是模拟退火算法的结果) 

 

 

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

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

相关文章

C#面:解释什么是partial view?

Partial view 相当于传统网页表格中的 user controls. 它的主要⽬的是为了重复使用这些视图&#xff0c;他们⼀般被放在⼀个共享⽂件夹⾥⾯。 html.partial() html.renderpartial() Partial View是 ASP.NET MVC中的一种视图类型&#xff0c;它允许我们将视图分解为多个可重用的…

pytest实战技巧之参数化应用

pytest是Python中最流行的测试框架之一。它提供了丰富的功能&#xff0c;可以帮助我们编写高效、可靠的测试用例。其中一个重要的功能就是参数化&#xff0c;它可以让我们用不同的数据组合来运行同一个测试用例&#xff0c;从而 提高测试覆盖率和效率。本文将介绍pytest参数化的…

香薰学习笔记

1 喷香水的方法 ChatGPT-4o 学习使用香水是提升个人形象的一个好方法。 喷香水的方法如下&#xff1a; 皮肤吸收&#xff1a;香水最好喷在皮肤上&#xff0c;因为皮肤的温度能帮助香水散发出更好的香味。喷在衣服上可能会影响香水的原始味道。脉搏点&#xff1a;将香水喷在脉搏…

springSecurity学习之springSecurity用户单设备登录

用户只能单设备登录 有时候在同一个系统中&#xff0c;只允许一个用户在一个设备登录。 之前的登陆者被顶掉 将最大会话数设置为1就可以保证用户只能同时在一个设备上登录 Override protected void configure(HttpSecurity http) throws Exception {http..anyRequest().aut…

微软蓝屏事件:全球IT基础设施的韧性考验与未来展望

在数字化时代&#xff0c;信息技术的飞速发展极大地推动了社会进步与产业升级&#xff0c;但同时也让全球IT基础设施的韧性与安全性面临着前所未有的挑战。近日&#xff0c;一场由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅震撼了整个科技界&#xff0…

“微软蓝屏”事件引发的深度思考:网络安全与系统稳定性的挑战与应对

“微软蓝屏”事件暴露了网络安全哪些问题&#xff1f; 近日&#xff0c;一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅成为科技领域的热点新闻&#xff0c;更是一次对全球IT基础设施韧性与安全性的深刻检验。这次事件&#xff0c;源于美国电脑安全…

数据结构中的八大金刚--------八大排序算法

目录 引言 一&#xff1a;InsertSort(直接插入排序) 二&#xff1a;ShellSort(希尔排序) 三&#xff1a;BubbleSort(冒泡排序) 四&#xff1a; HeapSort(堆排序) 五&#xff1a;SelectSort(直接选择排序) 六&#xff1a;QuickSort(快速排序) 1.Hoare版本 2.前后指针版本 …

JNI回调用中不同线程的env无法找到正确的kotlin的class

不同线程都需要通过 JavaVM 获取到的 JNIEnv 指针&#xff0c; 如果有两个线程有两个 env。 其中一个是jni接口自己传过来的&#xff0c;可以正常使用&#xff0c;正常获取kotlin中的class。但是通过 JavaVM 新获取的env 无法找到kotlin的class 1. 确保线程已附加到 JVM 确保…

学成在线开心学习

环境配置 第一章 项目介绍&环境搭建 项目背景 项目业务框架 项目技术架构 第二章 内容管理模块 本项目使用mybatis-plus的generator工程生成PO类、Mapper接口、Mapper的xml文件 模块工程 模型类的作用 课程查询接口 controller ApiOperation("课程查询接口&qu…

二、【Python】入门 - 【PyCharm】安装教程

往期博主文章分享文章&#xff1a; 【机器学习】专栏http://t.csdnimg.cn/sQBvw 目录 第一步&#xff1a;PyCharm下载 第二步&#xff1a;安装&#xff08;点击安装包打开下图页面&#xff09; 第三步&#xff1a;科学使用&#xff0c;请前往下载最新工具及教程&#xff1a…

【安卓开发】【Android】如何进行真机调试【注意事项】

一、所需原料 1、电脑&#xff08;安装有Android Studio开发工具&#xff09;&#xff1a; 2、安卓操作系统手机&#xff1a;笔者演示所用机型为huawei rongyao50&#xff0c;型号为NTU-AN00&#xff1a; 3、数据线&#xff08;usb-typeA&#xff09;一根。 二、操作步骤 1…

商汤提出的BRECQ量化框架是个什么?

商汤提出的BRECQ量化框架是个什么&#xff1f; 引言 近年来&#xff0c;深度学习在多个领域取得了显著进展&#xff0c;但其巨大的计算成本和内存占用问题逐渐凸显。为了压缩和加速已训练好的网络&#xff0c;量化成为了一种重要的技术手段。量化主要分为两类&#xff1a;量化…

IDEA插件:mybatis log plus,完整SQL语句输出插件

背景 idea中&#xff0c;我们开发项目时&#xff0c;在控制台中都会有日志输出&#xff0c;操作数据库也会有对应的SQL输出。 不过在控制台输出的SQL&#xff0c;不管增删改查&#xff0c;如果有传参&#xff0c;参数一般都是需要我们自己拼接&#xff0c;形成一个完整的、可…

Lottie:动态动画的魔法棒

文章目录 引言官网链接Lottie 的原理基础使用1. 导出动画2. 引入 Lottie 库3. 加载和播放动画 高级使用1. 动画控制2. 交互性3. 自定义动画例子&#xff1a;交互式按钮动画 优缺点优点缺点 结语 引言 Lottie 是 Airbnb 开源的一个动画库&#xff0c;它允许设计师在 Adobe Afte…

三极管和MOS管,二者的主要区别

1、工作性质&#xff1a;三极管用电流控制&#xff0c;MOS管属于电压控制. 2、成本问题&#xff1a;三极管便宜&#xff0c;mos管贵。 3、功耗问题&#xff1a;三极管损耗大。 4、驱动能力&#xff1a;mos管常用来电源开关&#xff0c;以及大电流地方开关电路。 三极管比较…

在Ubuntu子系统上安装宝塔面板(BT Panel)

在Ubuntu子系统上安装宝塔面板&#xff08;BT Panel&#xff09;&#xff0c;可以按照以下步骤进行&#xff1a; 更新系统软件包&#xff1a; 打开Ubuntu终端&#xff0c;输入以下命令更新系统软件包&#xff1a; sudo apt update && sudo apt upgrade -y安装必备的软件…

华清数据结构day4 24-7-19

链表的相关操作 linklist.h #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h> typedef int datatype; typedef struct Node {union{int len;datatype data;};struct Node *next; } Node, *NodePtr;NodePtr list_create(); NodePtr apply_node(datatype e); …

前端常用简化开发的框架和组件

一.BootStrap框架 BootStrap官网直达 Bootstrap是一个强大且易于使用的前端框架&#xff0c;适合各种规模的项目。它的响应式设计、丰富的组件和灵活的布局系统&#xff0c;使得开发者能够高效地构建现代化的网站。无论是初学者还是经验丰富的开发者&#xff0c;Bootstrap都能…

基于微信小程序+SpringBoot+Vue的刷题系统(带1w+文档)

基于微信小程序SpringBootVue的刷题系统(带1w文档) 基于微信小程序SpringBootVue的刷题系统(带1w文档) 本系统是将网络技术和现代的管理理念相结合&#xff0c;根据试题信息的特点进行重新分配、整合形成动态的、分类明确的信息资源&#xff0c;实现了刷题的自动化&#xff0c;…

scikit-learn中fit_transform会改变原始数据吗

在 Python 的 scikit-learn 库中&#xff0c;fit_transform 方法通常用于数据预处理阶段&#xff0c;比如在标准化、归一化、进行主成分分析&#xff08;PCA&#xff09;或其他转换时使用。这个方法同时执行 fit 方法和 transform 方法&#xff1a; fit&#xff1a;计算训练数…