遗传算法求解函数最大值

遗传算法求解函数的最大值

题目

求解函数:y=10sin(5x)+7|x-5|+10,x∈[0,10]的最大值

算法思路

步骤:

  1. 初始化操作,确定染色体的长度,变异率、交叉率、初始种群数量以及迭代的次数。
  2. 根据适应度函数的取值范围,对其进行编码成二进制,将0-10编码成20个二进制数。
  3. 随意生成第一代种群,用赌轮选择方法选择相同数量的下一代种群个体。并且记录最大适应度个体。
  4. 对种群个体按照交叉概率进行两两交叉。
  5. 对种群个体按照变异比率进行变异。
  6. 重复上述步骤,知道达到相应迭代次数。

代码分析

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。

运行结果分析

遗传算法求解函数最大值_第1张图片

当迭代次数达到30次以上时,函数的最大值几乎保持不变,说明了参数的选择较为合适。

遗传算法求解函数最大值_第2张图片

你可能感兴趣的:(python,算法)