遗传算法求解函数的最大值
题目
求解函数:y=10sin(5x)+7|x-5|+10,x∈[0,10]的最大值
算法思路
步骤:
- 初始化操作,确定染色体的长度,变异率、交叉率、初始种群数量以及迭代的次数。
- 根据适应度函数的取值范围,对其进行编码成二进制,将0-10编码成20个二进制数。
- 随意生成第一代种群,用赌轮选择方法选择相同数量的下一代种群个体。并且记录最大适应度个体。
- 对种群个体按照交叉概率进行两两交叉。
- 对种群个体按照变异比率进行变异。
- 重复上述步骤,知道达到相应迭代次数。
代码分析
import numpy as np
import math
import matplotlib.pyplot as plt
def fun(x):
return 10 * np.sin(5*x) + 7 * abs(x-5) + 10
lb = 0 #函数下界
ub = 10 #函数上界
G = 100 #迭代次数
l = 20 #二进制串的长度
N = 50 #种群的数量
f = np.random.randint(0, 2, (N, l)) #初始种群
cp = 0.8 #交叉率
mp = 0.1 #变异率
max_x = []
max_fun = []
best_x = 0
best_fun = 0
for i in range(G):
x = np.zeros(N) #解码以后的数字0-10
fit = np.zeros(N) #对应的函数值
for j in range(N):
m = 0
for k in range(l):
m = m + f[j][k] * (2 ** k) #求得每一个20位二进制码代表的十进制数
x[j] = (ub - lb) / (2 ** l - 1) * m + lb
fit[j] = fun(x[j])
maxfit = max(fit)
max_x.append(x[np.argmax(fit)])
max_fun.append(fit[np.argmax(fit)])
minfit = min(fit)
#记录当前最大适应度的个体
if(maxfit > best_fun):
best_fun = maxfit
best_x = x[np.argmax(fit)]
fit = (fit - minfit) / (maxfit - minfit)
sumfit = sum(fit)
fit_rate = fit / sumfit
fit_rate = np.cumsum(fit_rate) #对适应度比例累积
num = 0
#赌轮选择
nextf = np.random.randint(0, 2, (N, l))
while num < N:
prob = np.random.rand()
index = 0
while prob > fit_rate[index]:
index = index + 1
nextf[num] = f[index]
num = num + 1
#交叉
for j in range(round(N/2)):
cross_prob = np.random.rand()
if cross_prob < cp:
#随机生成交叉的位置
pos = np.random.randint(0, 1, l)
for k in range(l):
if pos[k] == 1:
temp = nextf[2*j][k]
nextf[2*j][k] = nextf[2*j+1][k]
nextf[2*j+1][k] = temp
#变异
j = 0
k = 0
while j < (mp * N): #变异的染色体条数
n_pos = np.random.randint(0, N)
while k < (l * mp): #变异的位置
l_pos = np.random.randint(0, l)
nextf[n_pos][l_pos] = not(nextf[n_pos][l_pos]) #取反
k = k + 1
j = j + 1
f = nextf
print('第', i, '次迭代的最大适应度:', maxfit)
x = np.arange(0, 10, 0.02)
y = fun(x)
plt.plot(x, y) #画出原函数的图像
plt.plot(max_x, max_fun, '^', color = 'green') #将每一代的最大适应度个体表示在图上
plt.plot(best_x, best_fun, 'o', color = 'red') #将最终结果表示在图上
plt.show()
关键分析
在本题目中,我们需要求解函数的最大值,根据适应度的定义,我们将函数值作为适应度。在赌轮选择中,将适应度累加,每一个个体适应度占比的多少决定了每一个个体选择的概率,因此适应度高的个体选择概率高。
通过两个染色体进行随机位置选择进行交叉,其概率由交叉因子决定。将两条染色体互换位置左边的基因互相交换。
变异是遗传算法一个非常关键的部分,变异可能会丢失某些关键信息,也可能创造出有价值的信息,因此变异可以防止遗传算法快速的收敛。变异由变异因子决定,在随机生成的位置中对二进制数进行去反操作,即0变为1,1变为0。
运行结果分析
当迭代次数达到30次以上时,函数的最大值几乎保持不变,说明了参数的选择较为合适。