遗传算法:
python编写的代码:
# -*- coding = utf-8 -*-
# @Time: 2021/7/17 10:27
# @Author : zy2015532
# @File: GA.py 2019.pro
# @Software: PyCharm
# @E-mail: zy2015532@gmail.com
import time
t0 = time.time()
import pandas as pd
import numpy as np
from matplotlib.pylab import style
import matplotlib.pyplot as plt
import random
import math
style.use('seaborn-deep')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
font1 = {'family': 'SimHei',
'weight': 'normal',
'size': 30, }
figsize = 20, 15
figure, ax = plt.subplots(figsize=figsize)
plt.tick_params(labelsize=23)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('SimHei') for label in labels]
NP = 100 # 种群数
L = 20 # 编码长度
Pc = 0.8# 交叉率
Pm = 0.8#变异率,稍微有点大,会过早“成熟",可以自行调整,0.001-0.1
G = 100# 进化代数
Xs = 10# 自变量上限
Xx = 6# 自变量下限
group = []#种群个体
Fit = []
Y = []
XX = []
nf = np.zeros([NP, L])
fbest = []
trace = np.zeros([G, 1])
X = []
Y = []
# 随机数生成初始种群
def Group():
group = []
for i in range(NP):
for j in range(L):
group.append(random.randint(0, 1))
Y = np.array(group).reshape(NP, L)
# print(Y)
return Y
# 二进制解码,换算成十进制
def Population(group):
XX.clear()
Fit.clear()
for i in range(NP):
m = 0
for j in range(L):
m += group[i, j] * 2 ** (j - 1)
m = Xx + (Xs - Xx) * m / (2 ** (L) - 1)
XX.append(m)
m = AimFunction(m)
# print("结束")
# print(m)
Fit.append(m)
# print(max(Fit))
# print(max(Fit))
rr = Fit.index(max(Fit))
# print(rr)
fbest = group[rr, :]
# print(fbest)
xbest = XX[rr]
Max_Fit = max(Fit)
# print(Max_Fit)
return xbest, fbest, Fit, Max_Fit
# 优化目标函数
def AimFunction(m):
result = m + 10 * np.sin(5 * m) + 7 * np.cos(4 * m)
return result
# 计算适应度,找出最佳个体遗传给下代。只有适应度大约平均适应度的#个体才会遗传给下代;
def Genetic(nf, group, Fit, L):
for i in range(NP):
Fit[i] = (Fit[i] - min(Fit)) / (max(Fit) - min(Fit))
if i % 50 == 0:
# print(Fit[i])
pass
sum_Fit = sum(Fit)
Fit_Value = Fit / sum_Fit
Fit_Value = sorted(Fit_Value, reverse=True)
# for i in range(1, NP):
# Fit_Value[i] = Fit_Value[i - 1] + Fit_Value[i]
# print(Fit_Value)
# print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
ms = sorted(np.random.rand(NP))
# print(ms)
fiti = 0
newi = 1
J = np.mean(Fit_Value)
nf[0, :] = fbest
while (newi < NP):
if (J) < Fit_Value[fiti]:
nf[newi, :] = group[fiti, :]
newi += 1
fiti += 1
if fiti > NP - 1:
break
# print(nf.shape)
# print(NP-newi)
# 这里稍微处理一下,引入外来新个体;
for i in range(newi, NP):
X = np.random.randint(0, 2, L)
nf[i, :] = X
# print("拼接完成")
return nf
# 交叉,基于概率交叉;
def Cross(nf):
nf[0,:]=fbest
for i in range(1, NP):
if i == NP-1:
break
p = np.random.rand()
# print(p)
# print("!!!")
if p < Pc:
q = np.random.randint(0, 2, L)
for j in range(0, L, 3):
if q[j] == 1:
temp = nf[i + 1, j]
nf[i + 1, j] = nf[i, j]
nf[i, j] = temp
# print("交叉了")
return nf
# 基于概率变异;
def Variation(nf):
nf[0, :] = fbest
p = np.random.rand()
m = 0
i = 1
while (i < NP):
if p > Pm:
h = np.random.randint(1, NP, 1)
for j in range(0, L):
g = np.random.randint(1, L, 1)
q = np.random.randint(0, 2, L)
if q[j] == 1:
nf[h, g] = int(not (nf[h, g]))
# print("变异了!!!!")
# m += 1;
i += 2
# print(m)
return nf
if __name__ == '__main__':
group = Group()
X = []
# 主循环开始,迭代一百次;
for epoch in range(G):
xbest, fbest, Fit, Max_Fit = Population(group)
nf = Genetic(nf, group, Fit, L)
nf = Cross(nf)
nf = Variation(nf)
group = nf
group[0, :] = fbest
group = nf
trace[epoch] = Max_Fit
X.append(xbest)
Y.append(Max_Fit)
# if epoch % 30 == 0:
# # print(nf)
# # print(trace)
# print("训练了第:", epoch, "次")
plt.plot(trace)
plt.show()
print("自变量取值为:", X[Y.index(max(Y))])
print("目标函数最大:", max(Y))
print("共耗时为:", "%.2f" % (time.time() - t0), "s")