f(x)=x^2的最小值(详解)
求[-L,L]范围内 F(x)=x^2的最小值。
- 生成popSize个[-L,L]内的随机数存在列表oldPop中,并计算通过适值函数计算适应值存在列表oldFit中;
- 进行maxGen次交叉、变异、选择操作;
- 交叉方式:中点交叉;
- 变异: yi’=xi’+N(0,sigma^2);
- 选择:从P∪P’里面的个体排序,取f(x)=x^2最小的前popsize个,组成新的种群
- 得到最优解
参数步骤
参数: 种群大小m, sigma,T
pop=[1,…,m] 定义种群
step1(种群初始化): P={x1,x2,…,xm} t=1
f(x)=x^2 x*=0
step2(交叉): [xi’,xj’]=crossover(xi,xj)
{
(Xi+-xj)/2 中点交差
其他方式: 凸组合交差方式 alpha*xi+(1-alphx)*xj
}
Step 3 (变异): xi’=xi’+N(0,sigma^2)
xj’=xj’+ N(0,sigma^2)
step4 (选择): P’={x1’,x2’,…,xm’}
从P∪P’里面的个体排序,取f(x)=x^2最小的前popsize个,组成新的种群
Step5(停止准则): t=t+1; if t<T goto step 2; else 停止
实现代码
- initialzePop.py
# 随机初始化产生popSize个[-L,+L]之间的实数,列表oldPop
import random
def initialzePop(popSize, L):
oldPop = []
for i in range(0, popSize):
n = random.uniform(-L, L)
oldPop.append(n)
# print(oldPop)
return oldPop
- fitnessFun.py
# 对每个个体x=oldPop[i],计算其适应度值oldFit[i]=x^2
def fitnessFun(oldPop):
oldFit = []
for i in range(0, len(oldPop)):
oldFit.append(oldPop[i]**2)
return oldFit
- crossover
# i1,i2 在[1,popSize]内,x1= oldPop[i1], x2= oldPop[i2], 随机选择两个个体x1,x2,
# 令y[i]=(x1+x2)/2,重复popSize次,生成新种群,
# 相当于 for i in range(1, popSize): 逐个的得到y[i], 结束后return y
import random
def crossover(oldPop):
y = []
popSize = len(oldPop)
for i in range(0, popSize):
i1 = random.randint(0, popSize-1)
i2 = random.randint(0, popSize-1)
# print(i1)
# print("5555555555555555555")
# print(i2)
x1 = oldPop[i1]
x2 = oldPop[i2]
y.append((x1 + x2) / 2)
return y
- mutation.py
# 对交差后的每个个体x, 高斯扰动y[i]=x+N(0,sigma^2), 生成新种群,return y
import random
def mutation(newPop, sigma):
y = []
for i in range(0, len(newPop)):
y.append(newPop[i] + random.gauss(0, sigma))
return y
- sel.py
# 将原种群和新种群的并集按适应度值排序,选择前面最好的popSize个作为下代,
# 函数体中直接调用排序函数,课本专门有一章可以有排序api函数调用的 sort
from fitnessFun import fitnessFun
def xx(x):
a = x**2
return a
def sel(oldPop, newPop):
oldPop.extend(newPop)
oldPop.sort(key=xx, reverse=True)
a = []
for i in range(len(newPop)):
a.append(oldPop[i])
b = fitnessFun(a)
return [a, b]
- main.py
from initialzePop import initialzePop
from fitnessFun import fitnessFun
from crossover import crossover
from mutation import mutation
from sel import sel
# from plot import plot
# 参数值
popSize = 50 # 种群规模
sigma = 1
L = 20
maxGen = 50 # 最大代数
oldPop = initialzePop(popSize, L)
oldFit = fitnessFun(oldPop)
for i in range(1, maxGen): # maxGen 表示进化最大世代数, 比如30,50,
# 交叉
newPop = crossover(oldPop)
# 变异
newPop = mutation(newPop, sigma)
# 选择
newFit = fitnessFun(newPop)
[oldPop, oldFit] = sel(oldPop, newPop)
# 输出最好的个体和适应度值,即为最优解和最优函数值
bestIndividual = oldPop[0]
bestFitness = oldFit[0]
print("最优解:%s"%bestIndividual)
print("最优函数值:%s"%bestFitness)
# plot(bestIndividual, bestFitness, maxGen)
plot.py(可视化)
import matplotlib.pyplot as plt
def plot(bestIndividual, bestFitness, maxGen):
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.tight_layout(pad=5)
plt.axis([-0.004, 200, -0.004, 0.006])
plt.grid()
plt.plot(maxGen, bestIndividual, )
plt.title('The bestIndividual changes with generations', fontsize=16)
plt.xlabel('generation', fontsize=16)
plt.ylabel('bestIndividual', fontsize=16)
# plt.savefig('out_14.jpg',bbox_inches='tight')
plt.show()
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.tight_layout(pad=5)
plt.axis([-0.004, 200, -0.004, 0.006])
plt.grid()
plt.plot(maxGen, bestFitness, )
plt.title('The bestFitness changes with generations', fontsize=16)
plt.xlabel('generation', fontsize=16)
plt.ylabel('bestFitness', fontsize=16)
# plt.savefig('out_14.jpg',bbox_inches='tight')
plt.show()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律