说明
基础内容源自 智能优化算法及其MATLAB实例(第二版)源程序
源程序为 matlab 代码,笔者在此基础上将 matlab 代码转化为 python 代码实现
一、标准遗传算法求函数极值
GA21.m
%%%%%%%%%%%%%%%%%%%%标准遗传算法求函数极值%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
NP=50; %种群数量
L=20; %二进制数串长度
Pc=0.8; %交叉率
Pm=0.1; %变异率
G=100; %最大遗传代数
Xs=10; %上限
Xx=0; %下限
f=randint(NP,L); %随机获得初始种群
% 现在比较新的 matlab 版本中,需要将 randint 函数换成 randi 函数
%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%%%%
for k=1:G
%%%%%%%%%%%%将二进制解码为定义域范围内十进制%%%%%%%%%%%%%%
for i=1:NP
U=f(i,:);
m=0;
for j=1:L
m=U(j)*2^(j-1)+m;
end
x(i)=Xx+m*(Xs-Xx)/(2^L-1);
Fit(i)= func1(x(i));
end
maxFit=max(Fit); %最大值
minFit=min(Fit); %最小值
rr=find(Fit==maxFit);
fBest=f(rr(1,1),:); %历代最优个体
xBest=x(rr(1,1));
Fit=(Fit-minFit)/(maxFit-minFit); %归一化适应度值
%%%%%%%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%%%%%%%
sum_Fit=sum(Fit);
fitvalue=Fit./sum_Fit;
fitvalue=cumsum(fitvalue);
ms=sort(rand(NP,1));
fiti=1;
newi=1;
while newi<=NP
if (ms(newi))<fitvalue(fiti)
nf(newi,:)=f(fiti,:);
newi=newi+1;
else
fiti=fiti+1;
end
end
%%%%%%%%%%%%%%%%%%%%%%基于概率的交叉操作%%%%%%%%%%%%%%%%%%
for i=1:2:NP
p=rand;
if p<Pc
q=randint(1,L);
for j=1:L
if q(j)==1;
temp=nf(i+1,j);
nf(i+1,j)=nf(i,j);
nf(i,j)=temp;
end
end
end
end
%%%%%%%%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%%%%%%%%%%%%
i=1;
while i<=round(NP*Pm)
h=randint(1,1,[1,NP]); %随机选取一个需要变异的染色体
for j=1:round(L*Pm)
g=randint(1,1,[1,L]); %随机需要变异的基因数
nf(h,g)=~nf(h,g);
end
i=i+1;
end
f=nf;
f(1,:)=fBest; %保留最优个体在新种群中
trace(k)=maxFit; %历代最优适应度
end
xBest; %最优个体
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
func1.m
%%%%%%%%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function result=func1(x)
fit= x+10*sin(5*x)+7*cos(4*x);
result=fit;
GA21.py
import numpy as np
import matplotlib.pyplot as plt
import math
# 用来正常显示中文标签及负号
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 定义目标函数 func1
def func1(x):
return x+10*sin(5*x)+7*cos(4*x) # func1.m 对应的适应度函数
# 初始化参数
NP = 50 # 种群数量
L = 20 # 二进制数串长度
Pc = 0.8 # 交叉率
Pm = 0.1 # 变异率
G = 100 # 最大遗传代数
Xs = 10 # 上限
Xx = 0 # 下限
# 随机获得初始种群
f = np.random.randint(2, size=(NP, L)) # 表示生成一个(NP, L)形状的二维数组,元素只能为0、1
# 遗传算法循环
trace = np.zeros(G) # 创建一个全为0的数组
for k in range(G):
# 将二进制解码为定义域范围内十进制
x = np.zeros(NP)
for i in range(NP):
m = np.sum(f[i,:] * 2 ** np.arange(L)[::-1]) # 计算二进制数组f[i,:]的十进制等价值
x[i] = Xx + m * (Xs - Xx) / (2**L - 1) # 将十进制数映射到区间上下界
Fit = np.array([func1(xi) for xi in x]) # 计算适应度值
maxFit = np.max(Fit) # 最大值
minFit = np.min(Fit) # 最小值
rr = np.where(Fit == maxFit)[0]
fBest = f[rr[0], :] # 历代最优个体
xBest = x[rr[0]]
Fit = (Fit - minFit) / (maxFit - minFit) # 归一化适应度值
# 基于轮盘赌的复制操作
sum_Fit = np.sum(Fit)
fitvalue = Fit / sum_Fit
fitvalue = np.cumsum(fitvalue)
ms = np.sort(np.random.rand(NP))
fiti = 0
newi = 0
nf = np.zeros((NP, L), dtype=int)
while newi < NP:
if ms[newi] < fitvalue[fiti]:
nf[newi, :] = f[fiti, :]
newi += 1
else:
fiti += 1
# 基于概率的交叉操作
for i in range(0, NP, 2):
p = np.random.rand()
if p < Pc:
q = np.random.randint(1, L + 1)
mask = np.random.randint(1, L + 1, size=L) == q
nf[i, mask], nf[i + 1, mask] = nf[i + 1, mask], nf[i, mask]
# 基于概率的变异操作
i = 0
while i <= round(NP * Pm):
h = np.random.randint(1, NP + 1) - 1
for _ in range(round(L * Pm)):
g = np.random.randint(1, L + 1) - 1
nf[h, g] = 1 - nf[h, g]
i += 1
f = nf
f[0, :] = fBest # 保留最优个体在新种群中
trace[k] = maxFit # 历代最优适应度
# 输出最优个体
print("xBest:", xBest)
# 绘图
plt.plot(trace)
plt.xlabel('迭代次数')
plt.ylabel('目标函数值')
plt.title('适应度进化曲线')
plt.show()
xBest: 7.8567865913263235