遗传算法求解函数最大值----python代码实现

遗传算法:

遗传算法(Genetic Algorithm,GA)是一种启发式优化算法,灵感来自于达尔文的进化论中的自然选择和遗传机制。它模拟了自然界中生物进化的过程,用于解决优化问题,特别是那些涉及搜索、优化、迭代改进的复杂问题。

遗传算法基本原理:
编码个体: 在遗传算法中,解决方案(也称为个体)被编码成染色体或基因组,通常使用二进制串、实数编码、排列等不同的方式来表示问题的解空间。
初始化种群: 初始阶段,随机生成一组个体作为初始种群,代表问题的可能解。
评估适应度: 根据问题的目标函数或评价标准计算每个个体的适应度(Fitness),即解决方案的好坏程度。
选择操作: 通过选择操作,以一定的概率从当前种群中选出适应度较高的个体作为父母个体,用于产生下一代。
交叉操作: 选出的父母个体进行交叉(Crossover),即交换染色体中的信息,生成新的个体。
变异操作: 在新生成的个体中引入变异(Mutation),以增加搜索空间的多样性,并帮助避免陷入局部最优。
更新种群: 将新生成的个体与原有种群中的个体结合,形成新的种群,并根据适应度对它们进行排序。
重复迭代: 通过不断重复选择、交叉和变异操作,生成新的个体,直到达到停止条件(例如达到最大迭代次数或适应度满足一定要求)。
输出结果: 输出具有最高适应度值(最优解)对应的个体,作为问题的解决方案。

遗传算法求解函数最大值的一般步骤:

定义问题: 确定要优化的目标函数。这可能是一个在一定区间内的单变量或多变量函数。
编码个体: 将函数的自变量(单变量或多变量)编码为遗传算法的个体,例如二进制串、实数编码等。
初始化种群: 随机生成初始群体(个体),并将其编码成染色体。
计算适应度函数: 根据目标函数计算每个个体的适应度值,即函数值(或者在寻找最大值时是负函数值)。
选择操作: 选择具有较高适应度值的个体作为父母个体,以用于产生下一代。通常选择策略包括轮盘赌选择、竞争性选择等。
交叉操作: 通过交叉操作(交叉互换染色体中的信息)生成新个体。
变异操作: 对新生成的个体进行变异,以增加搜索空间,避免局部最优。
更新种群: 生成下一代种群,并计算其适应度值。
收敛条件: 当达到最大迭代次数或适应度值满足停止条件时停止优化过程。
输出结果: 输出具有最高适应度值(函数值)的个体对应的解,即函数的最大值点。 确定要优化的目标函数。这可能是一个在一定区间内的单变量或多变量函数。

示例:
假设我们要优化一个单变量函数,例如求解函数 f(x) = x^2 - 4x + 4 的最大值。
初始化种群: 随机生成一组个体(x 的取值)作为初始种群。
编码个体: 将这些个体编码成染色体(例如实数编码)。
计算适应度: 根据函数 f(x) 计算每个个体的适应度(即函数值)。
选择、交叉、变异: 重复进行选择、交叉和变异操作,生成新的个体。
更新种群、迭代优化: 重复这些步骤,直到达到停止条件。
输出结果: 输出适应度最高的个体所对应的 x 值,即为函数的最大值点。

注意:遗传算法可能会受到参数设置、种群大小、交叉率、变异率等参数的影响。调整这些参数以及合适地选择适应度函数和停止条件对于获得较好的优化效果是很重要的。

python代码实现:

import matplotlib.pyplot as plt
import math
import random
import numpy as np

pop_size = 50  # 种群数量
PC=0.6 # 交叉概率
PM=0.1 #变异概率
X_max=10     #最大值
X_min=0     #最小值
DNA_SIZE=10  #DNA长度与保留位数有关,2**10 当前保留3位小数点
N_GENERATIONS=100

#求解的目标表达式为:
x=random.randint(0,5)
y = 10 * math.sin(5 * x) + 7 * math.cos(4 * x)


def aim(x):  return np.sin(5*x)+7*np.cos(4*x)    #求函数最大值                         #return 10*x #np.sin(5*x)+7*np.cos(4*x)   
def f1(pop): #DNA翻译  translateDNA
   return   pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) *(X_max-X_min)/ float(2**DNA_SIZE-1) +X_min
def f2(pred):  #获得适应性 get_fitness
    return pred + 1e-3 - np.min(pred)
def f3(pop, fitness): #选择 select
    idx = np.random.choice(np.arange(pop_size), size=pop_size, replace=True,p=fitness/fitness.sum())
    return pop[idx]
def f4(parent, pop):  #交叉 crossover
    if np.random.rand() < PC:
        i_ = np.random.randint(0, pop_size, size=1)
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool)
        parent[cross_points] = pop[i_, cross_points]
    return parent
def f5(child,pm):   #变异 mutate
    for point in range(DNA_SIZE):
        if np.random.rand() < pm:
            child[point] = 1 if child[point] == 0 else 0
    return child
pop = np.random.randint(2, size=(pop_size, DNA_SIZE))
plt.ion()
plt.plot(x,aim(x))
for i in range(N_GENERATIONS):
    #解码
    X_value=f1(pop)
    #获取目标函数值
    F_values =aim(f1(pop))
    sca = plt.scatter(f1(pop), F_values, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)
    #获取适应值
    fitness =f2(F_values)
    if(i==0):
        max=np.max(F_values)
        max_DNA = pop[np.argmax(F_values), :]
    if(max<np.max(F_values)):
        max=np.max(F_values)
        max_DNA=pop[np.argmax(F_values), :]
    if (i % 10 == 0):
        print("Most fitted value and X: \n",
              np.max(F_values), f1(pop[np.argmax(F_values), :]))
    #选择
    pop = f3(pop,fitness)
    pop_copy = pop.copy()
    #交叉 变异
    for parent in pop:
        child = f4(parent,pop_copy)
        child = f5(child,pm=0.1)
        parent[:] = child
print("目标函数最大值为:",max)
print("其DNA值为:",max_DNA)
print("其X值为:",f1(max_DNA))
plt.ioff()
plt.show()

代码结果
在这里插入图片描述

总结:

遗传算法由于是借鉴了生物进化论,将要解决的问题模拟成一个生物进化的过程,通过复制、交叉、突变等操作产生下一代的解,并逐步淘汰掉适应度函数值低的解,增加适应度函数值高的解。这样进化N代后就很有可能会进化出适应度函数值很高的个体。所以随着迭代的增加,高适应度的个体逐渐在增加,低适应度的个体逐渐在减少。非常直白的显示了物竞天择,适者生存的观点。

  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值