基于Python实现的遗传算法求最值问题
遗传算法求最值问题
目录
人工智能第三次实验报告 1
遗传算法求最值问题 1
一 、遗传算法 1
1.1 遗传算法简介 1
1.2 遗传算法基本要素 2
4. 设定遗传操作: 2
1.3 遗传算法一般步骤 2
二 、程序说明 2
2.1 控制参数 2
2.2 编码规则 3
2.3 选择初始群体 3
2.4 适应度函数 4
三 、参数测试 5
四 、算法改进 6
4.1 最佳个体保存 6
4.2 双倍体遗传 7
附 录 7
1 import numpy as np 8
14 def F(x, y): # 问题函数 8
一 、遗传算法
1.1遗传算法简介
遗传算法是一种进化算法,基于自然选择和生物遗传等生物进化机制的一种搜索算法,其通过选 择、重组和变异三种操作实现优化问题的求解。它的本质是从原问题的一组解出发改进到另一组较好的 解,再从这组改进的解出发进一步改进。在搜索过程中,它利用结构和随机的信息,是满足目标的决策 获得最大的生存可能,是一种概率型算法。
遗传算法主要借用生物中“适者生存”的原则,在遗传算法中,染色体对应的是数据或数组,通常由 一维的串结构数据来表示。串上的各个位置对应一个基因座,而各个位置上所取的值对等位基因。遗传 算法处理的是基因型个体,一定数量的个体组成了群体。群体的规模就是个体的数目。不同个体对环境 的适应度不同,适应度打的个体被选择进行遗传操作产生新个体。每次选择两个染色体进行产生一组新 染色体,染色体也可能发生变异,得到下一代群体。
1.2遗传算法基本要素
1.参数编码:可以采用位串编码、实数编码、多参数级联编码等
2.设定初始群体:
1.启发 / 非启发给定一组解作为初始群体
2.确定初始群体的规模
3.设定适应度函数:本文转载自http://www.biyezuopin.vip/onews.asp?id=16718将目标函数映射为适应度函数,可以进行尺度变换来保证非负、归一等特性
4.设定遗传操作:
1.选择:从当前群体选出一系列优良个体,让他们产生后代个体,一般采用蒙特卡洛法,即按适 应度占比分配概率
2.交叉:两个个体的基因进行交叉重组来获得新个体
3.变异:随机变动个体串基因座上的某些基因
5.设定控制参数:例如变异概率、交叉程度、迭代上限等。
import numpy as np
from matplotlib.ticker import MultipleLocator
from numpy.ma import cos
import matplotlib.pyplot as plt
from matplotlib import cm
import time
from mpl_toolkits.mplot3d import Axes3D
import datetime
from scipy.interpolate import make_interp_splineDNA_SIZE = 12 # 编码长度
POP_SIZE = 100 # 种群大小
CROSS_RATE = 0.8 # 交叉率
MUTA_RATE = 0.15 # 变异率
Iterations = 100 # 代次数
X_BOUND = [0,10] # X区间
Y_BOUND = [0,10] # Y区间def F(x, y): # 问题函数return (6.452*(x+0.125*y)*(cos(x)-cos(2*y))**2)/(0.8+(x-4.2)**2+2*(y-7)**2)+3.226*ydef decodeDNA(pop): # 基因解码x_pop = pop[:,1::2] # 奇数列表示 X:取 pop 的奇数位y_pop = pop[:,::2] # 偶数列表示 Y:取 pop 的偶数位x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0] # 二进制转十进制,在归一化塞入区间[0,10]中y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0] # 二进制转十进制,在归一化塞入区间[0,10]中return x,ydef getfitness(pop): # 计算适应度函数x,y = decodeDNA(pop)temp = F(x, y)return (temp - np.min(temp)) + 0.0001 # 减去最小的适应度是为了防止适应度出现负数def select(pop, fitness): # 根据适应度选择(蒙特卡罗)temp = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=(fitness)/(fitness.sum()))return pop[temp]def crossmuta(pop, CROSS_RATE): # 种群的交叉变异操作new_pop = []for i in pop: # 遍历种群中的每一个个体,将该个体作为父代temp = i # 子代先得到父亲的全部基因if np.random.rand() < CROSS_RATE: # 以交叉概率发生交叉j = pop[np.random.randint(POP_SIZE)] # 从种群中随机选择另一个个体,并将该个体作为母代cpoints1 = np.random.randint(0, DNA_SIZE*2-1) # 随机产生交叉的两个点(区间:[cpoints1, cpoints2])cpoints2 = np.random.randint(cpoints1,DNA_SIZE*2)temp[cpoints1:cpoints2] = j[cpoints1:cpoints2] # 子代得到位于交叉点后的母代的基因mutation(temp,MUTA_RATE) # 每一个后代以变异率发生变异new_pop.append(temp)return new_popdef mutation(temp, MUTA_RATE):if np.random.rand() < MUTA_RATE: # 以MUTA_RATE的概率进行变异mutate_point = np.random.randint(0, DNA_SIZE) # 随机产生一个实数,代表要变异基因的位置temp[mutate_point] = temp[mutate_point] ^ 1 # 将变异点的二进制为反转def print_info(pop): # 用于输出结果fitness = getfitness(pop)maxfitness = np.argmax(fitness) # 返回最大值的索引值print("迭代次数: ", Iterations)print("最大适应度: ", fitness[maxfitness])x,y = decodeDNA(pop)print("最优基因型: ", pop[maxfitness])print("最优解 (x,y) = ", (x[maxfitness], y[maxfitness]))print("最优值 F(x,y) = ", F(x[maxfitness],y[maxfitness]))# 画图
def plot_3d(ax):X = np.linspace(*X_BOUND, 100)Y = np.linspace(*Y_BOUND, 100)X, Y = np.meshgrid(X, Y)Z = F(X, Y)ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm)ax.set_zlim(-20, 100)ax.set_xlabel('x')ax.set_ylabel('y')ax.set_zlabel('z')plt.pause(3)plt.show()# 画图
def draw(l1, l2, l3, l4, testStr):ax1 = plt.subplot(131)ax1.plot(l1, l2, 'b')ax1.set_xlabel(testStr)ax1.set_ylabel("COST_TIME")ax1.set_ylim(bottom=0)ax2 = plt.subplot(132)ax2.plot(l1, l4, 'r')ax2.set_xlabel(testStr)ax2.set_ylabel("BEST_F(X,Y)")ax2.set_ylim(bottom=0)ax3 = plt.subplot(133)ax3.plot(l1, l3, 'g')ax3.set_xlabel(testStr)ax3.set_ylabel("BEST_FITNESS")ax3.set_ylim(bottom=0)plt.show()# 研究单一参数的变化对求解结果和求解耗时的影响# 编码长度测试范围:[6,30],每一个长度重复测试 10 次来减小随机误差
def DNA_SIZE_TEST():dna_size_list = range(6,30,2)cost_time = []best_fitness = []best_f = []k = 10 # 重复次数,减小随机误差for i in dna_size_list:total_time = 0total_fitness = 0total_f = 0for j in range(k):global DNA_SIZEDNA_SIZE= istart_t = time.time()pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代x, y = decodeDNA(pop)pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = time.time()fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)total_time += (end_t - start_t)total_fitness += fitness[maxfitness]total_f += F(x[maxfitness], y[maxfitness])cost_time.append(total_time / k)best_fitness.append(total_fitness / k)best_f.append(total_f / k)draw(dna_size_list, cost_time, best_fitness, best_f, "DNA_SIZE")# 种群大小测试范围:[20,800],每一个长度重复测试 3 次来减小随机误差
def POP_SIZE_TEST():pop_size_list = range(20,800,20)cost_time = []best_fitness = []best_f = []k = 3for i in pop_size_list:total_time = 0total_fitness = 0total_f = 0for j in range(k):global POP_SIZEPOP_SIZE= istart_t = time.time() # 开始计时pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代x, y = decodeDNA(pop)pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = time.time()fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)total_time += (end_t - start_t)total_fitness += fitness[maxfitness]total_f += F(x[maxfitness], y[maxfitness])cost_time.append(total_time / k)best_fitness.append(total_fitness / k)best_f.append(total_f / k)draw(pop_size_list, cost_time, best_fitness, best_f, "POP_SIZE")# 交叉率测试范围:[0,1],每一个长度重复测试 10 次来减小随机误差
def CROSS_RATE_TEST():r_list = range(0,21)cr_list = []for i in r_list:cr_list.append(i * 0.05)cost_time = []best_fitness = []best_f = []k = 10for i in r_list:total_time = 0total_fitness = 0total_f = 0for j in range(k):global CROSS_RATECROSS_RATE = cr_list[i]start_t = time.time() # 开始计时pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代x, y = decodeDNA(pop)pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = time.time()fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)total_time += (end_t - start_t)total_fitness += fitness[maxfitness]total_f += F(x[maxfitness], y[maxfitness])cost_time.append(total_time / k)best_fitness.append(total_fitness / k)best_f.append(total_f / k)draw(cr_list, cost_time, best_fitness, best_f, "CROSS_RATE")# 变异率测试范围:[0,1],每一个长度重复测试 10 次来减小随机误差
def MUTA_RATE_TEST():r_list = range(0, 21)mr_list = []for i in r_list:mr_list.append(i * 0.05)cost_time = []best_fitness = []best_f = []k = 10for i in r_list:total_time = 0total_fitness = 0total_f = 0for j in range(k):global MUTA_RATEMUTA_RATE = mr_list[i]start_t = time.time() # 开始计时pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代x, y = decodeDNA(pop)pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = time.time()fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)total_time += (end_t - start_t)total_fitness += fitness[maxfitness]total_f += F(x[maxfitness], y[maxfitness])cost_time.append(total_time / k)best_fitness.append(total_fitness / k)best_f.append(total_f / k)draw(mr_list, cost_time, best_fitness, best_f, "MUTA_RATE")# 迭代次数测试范围:[1,1000],每一个长度重复测试 5 次来减小随机误差
def ITERATION_TEST():i_list = range(1, 1010, 50)cost_time = []best_fitness = []best_f = []k = 10 # 重复次数,减小随机误差for i in i_list:total_time = 0total_fitness = 0total_f = 0for j in range(k):global IterationsIterations = istart_t = time.time()pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代x, y = decodeDNA(pop)pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = time.time()fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)total_time += (end_t - start_t)total_fitness += fitness[maxfitness]total_f += F(x[maxfitness], y[maxfitness])cost_time.append(total_time / k)best_fitness.append(total_fitness / k)best_f.append(total_f / k)draw(i_list, cost_time, best_fitness, best_f, "ITERATIONS")# 非优化迭代遗传代码
def NonOpt():start_t = datetime.datetime.now()pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数pop = select(pop, fitness) # 选择生成新的种群end_t = datetime.datetime.now()print("非优化\n耗时: ",(end_t - start_t))print_info(pop)fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)return F(x[maxfitness],y[maxfitness])# 最佳个体保存优化遗传代码
def Opt_1():start_t = datetime.datetime.now()pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数for _ in range(Iterations): # 迭代 N 代pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)fitness = getfitness(pop) # 计算种群每一个基因的适应度函数best = pop[np.argmax(fitness)]pop = select(pop, fitness) # 选择生成新的种群pop[0] = bestend_t = datetime.datetime.now()print("\n最佳个体保存\n耗时: ",(end_t - start_t))print_info(pop)fitness = getfitness(pop)maxfitness = np.argmax(fitness)x, y = decodeDNA(pop)return F(x[maxfitness],y[maxfitness])# 对比测试最佳个体保存与非优化代码的性能
def OPT1_TEST():i_list = range(100)f = []f_opt = []for i in i_list:print(i)f.append(NonOpt())f_opt.append(Opt_1())f.sort()f_opt.sort()plt.plot(i_list, f, marker='o', label="Non Optimized")plt.plot(i_list, f_opt, marker='^', label="Best Preserve")plt.gca().xaxis.set_major_locator(MultipleLocator(10))plt.legend()plt.show()if __name__ == "__main__":OPT1_TEST()# DNA_SIZE_TEST()# POP_SIZE_TEST()# CROSS_RATE_TEST()# MUTA_RATE_TEST()# ITERATION_TEST()# fig = plt.figure()# ax = Axes3D(fig)# plt.ion()# plot_3d(ax)## start_t = datetime.datetime.now()# pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) # pop(二维矩阵) = 种群数 * (DNA长度 * 2) 个 0,1 随机数# for _ in range(Iterations): # 迭代 N 代# x, y = decodeDNA(pop)## # 更新画图# if 'sca' in locals():# sca.remove()# sca = ax.scatter(x, y, F(x, y), c='black', marker='o')# plt.show()# plt.pause(0.1)## pop = np.array(crossmuta(pop, CROSS_RATE)) # 对种群进行交叉(cross)和变异(muta)# fitness = getfitness(pop) # 计算种群每一个基因的适应度函数# pop = select(pop, fitness) # 选择生成新的种群## end_t = datetime.datetime.now()# print("耗时: ",(end_t - start_t))# print_info(pop)# plt.ioff()# plot_3d(ax)
基于Python实现的遗传算法求最值问题相关推荐
- python利用以下公式求π的值_Python 计算 π 值的简单示例
这篇文章主要为大家详细介绍了Python 计算 π 值的简单示例,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! π是一 ...
- python利用以下公式求π的值_使用Python计算 π 值
π是一个无数人追随的真正的神奇数字.我不是很清楚一个永远重复的无理数的迷人之处.在我看来,我乐于计算π,也就是计算π的值.因为π是一个无理数,它 是无限的.这就意味着任何对π的计算都仅仅是个近似值.如 ...
- 基于Python的蒙特卡罗方法估计Pi值的实现
蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法.是 ...
- Python实现遗传算法求函数最值
Python实现遗传算法求函数最值 详细源代码:GA.py 1.算法过程图解 2.详细过程举例说明 (1)待求解方程 (2)确定编码方案 主要是确定编码长度: def segment_length(s ...
- 行列式求值 按照代数余子式求和 基于python
行列式求值 按照代数余子式求和 基于python 本代码固定了行索引,从一开始 代数余子式百度百科介绍 import numpy as npn_array = np.array([[1,2,3,4], ...
- python多元函数求解_使用遗传算法求二元函数的最小值
二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...
- 独家 | 基于Python的遗传算法特征约简(附代码)
作者:Ahmed Gad 翻译:张睿毅 校对:丁楠雅 本文4700字,建议阅读15分钟. 本教程主要使用numpy和sklearn来讨论如何使用遗传算法(genetic algorithm,GA)来减 ...
- 遗传算法求最短路径(旅行商问题)python实现
问题描述 一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地.应如何选择行进路线,以使总的行程最短. 对于n个城市的TSP,本文利用python分别实现遗传算 ...
- python求函数极值_python 遗传算法求函数极值的实现代码
废话不多说,大家直接看代码吧! """遗传算法实现求函数极大值-Zjh""" import numpy as np import rando ...
最新文章
- python库引用的3种方式比较
- (012) java后台开发之Apache与Tomcat有什么关系和区别
- av_interleaved_write_frame -22
- C++风格与C风格文件读写效率测试-vs2015,vs2017
- 微信小程序,引用扩展组件提示“没有找到可以构建的NPM包”
- JDK 7的算法和数据结构
- pytorch学习笔记(十一):pytorch实现多层感知机
- Win XP环境Tuxedo8.1安装、配置指南
- FastSpring.NET V2.05 final 发布[集成Spring.net NHibernate Ajax]
- SQL Server 创建游标(cursor)
- 磁力计椭球拟合使用篇 IMU 加速度、电子罗盘校准
- 基于数据报表处理系统(VUE+SSM+MySQL)
- 数据结构课程设计(选):连连看
- 存储卡规格等级全解!SD卡TF卡都能用
- MIT 线性代数导论 第十九、二十讲:行列式公式、代数余子式、克拉默法则
- 使 div 水平 垂直 居中
- BottledWater-PG:PostgreSQL集成Kafka的实时数据交换平台
- 蓝凌OA自定义公式样例库
- java实现分数相加减
- GK110和GK104