遗传算法求解实例以及实现代码

遗传算法求解实例

参考实例链接:https://blog.csdn.net/m0_38101326/article/details/90642193

除了包含实例,还包括我对于代码的理解

从中学习的主要的内容是这个链接:

遗传算法二进制串位数的确定
博客的画图没用采用matplotlib,用的是pyecharts

问题的提出,现在需要求解下面这个函数式在给定区间的最大值。

在这里插入图片描述

#我们先使用python画出函数在给定区间的图像
import numpy as np
import math
import pyecharts
import pyecharts.options as opts
from pyecharts.charts import Line
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB

pi = math.pi
x = np.arange(-1,2,0.01)
y = x*(np.sin(10*pi*x)) +2

line = Line()
line.add_xaxis(x)
line.add_yaxis("函数值",y,label_opts=opts.LabelOpts(is_show=False),is_symbol_show=False)
line.set_global_opts(title_opts=opts.TitleOpts(title="函数xsin(10πx)+2图像"))
line.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
line.load_javascript()
line.render_notebook()

图像如下:
遗传算法求解实例以及实现代码_第1张图片

遗传算法的一般步骤

1.初始化种群

2.计算每个种群的适应度值

3.按照适应度来选择个体

4.交叉和变异

5.重复2,3,4步直到达到收敛的条件

import random
import numpy as np
import pyecharts
import pyecharts.options as opts
from pyecharts.charts import Line
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB

#初始化种群
def oripopular(num):
    popular = []
    for i in range(num):
        x = random.uniform(-1,2)#在此范围内随机生成一个浮点数
        popular.append(x)
    return popular

#编码,也就是从基本的函数中的数据编码为二进制数据
def encode(popular):
    popular_gene = []
    for i in range(0,len(popular)):
        data = int((popular[i]-(-1))/ 3 * 2**18)#染色体的序列为18bit   这个地方的具体来的公式看链接,而且这个地方作者似乎省略了减1。
        bin_data = bin(data)
        for i in range(len(bin_data)-2,18):#序列长度不足补0
            bin_data = bin_data[0:2] + '0' + bin_data[2:]#前面三位是整数部分?后面10位是小数部分?
        popular_gene.append(bin_data)
    return popular_gene

#解码,即编码的逆过程
def decode(popular_gene):
    fitness = []
    for i in range(len(popular_gene)):
        x = (int(popular_gene[i],2)/ 2**18)*3-1
        value = x*np.sin(10*np.pi*x)+2
        fitness.append(value)
    return fitness

#选择和交叉。选择采用轮盘的方式,交叉概率为0.66
def choice_ex(popular_gene):
    fitness = decode(popular_gene)#解码出适应度值
    sum_fit_value = 0
    for i in range(len(fitness)):
        sum_fit_value += fitness[i]#所有的适应度值相加
    #各个个体选择的概率
    probability = []
    for i in range(len(fitness)):
        probability.append(fitness[i]/sum_fit_value)
    #概率分布
    probability_sum = []
    for i in range(len(fitness)):
        if i == 0:
            probability_sum.append(probability[i])
        else:
            probability_sum.append(probability_sum[i-1] + probability[i])
    
    #选择
    popular_new = []
    for i in range(int(len(fitness)/2)):
        temp = []
        for j in range(2):
            rand = random.uniform(0,1)#在0-1之间随机产生一个浮点数,这个浮点数的作用是来判断对应的概率的值是否保留?
            for k in range(len(fitness)):
                if k == 0:
                    if rand < probability_sum[k]:
                        temp.append(popular_gene[k])
                else:
                    if (rand > probability_sum[k-1]) and (rand < probability_sum[k]):
                        temp.append(popular_gene[k])
            
            #交叉,交叉率为0.66
        is_change = random.randint(0,2)
        if is_change:
            temp_s = temp[0][9:15]
            temp[0] = temp[0][0:9] + temp[1][9:15] + temp[0][15:]
            temp[1] = temp[1][0:9] + temp_s + temp[1][15:]
                
        popular_new.append(temp[0])
        popular_new.append(temp[1])
            
    return popular_new

#变异 概率为0.05
def variation(popular_new):
    for i in range(len(popular_new)):
        is_variation = random.uniform(0,1)
        if is_variation < 0.02:
            rand =random.randint(2,19)
            if popular_new[i][rand] == "0":
                popular_new[i] = popular_new[i][0:rand] + '1' + popular_new[i][rand+1:]
            else:
                popular_new[i] = popular_new[i][0:rand] + '0' + popular_new[i][rand+1:]
            
    return popular_new

#主函数
if __name__ == "__main__":
    #初始化原始种群,一百个个体
    num = 100
    ori_popular = oripopular(num)
    #得到原始种群的基因
    ori_popular_gene = encode(ori_popular) #18位基因
    new_popular_gene = ori_popular_gene
    y = []
    for i in range(1000):#迭代的次数。繁殖1000代
        new_popular_gene = choice_ex(new_popular_gene) #选择和交叉
        new_popular_gene = variation(new_popular_gene) #变异
        #取当代所有个体适应度平均值
        new_fitness = decode(new_popular_gene)
        sum_new_fitness = 0
        for j in new_fitness:
            sum_new_fitness += j
        y.append(sum_new_fitness/len(new_fitness))
    
    #使用pyecharts画图
    x = np.linspace(0,1000,1000)
    line = Line()
    line.add_xaxis(x)
    line.add_yaxis("函数值",y,label_opts=opts.LabelOpts(is_show=False),is_symbol_show=False)
#     line.add_yaxis("函数值",y,label_opts=opts.LabelOpts(is_show=False))
    line.set_global_opts(title_opts=opts.TitleOpts(title="GA算法"))
    line.load_javascript()
    line.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    line.load_javascript()
    line.render_notebook()

运行结果如下:
遗传算法求解实例以及实现代码_第2张图片
函数的最大值是在接近4的位置,能从博客最前面的函数值的图看出来,遗传算法大概几十次后就收敛了,可以看出效果比较好。
参考链接
遗传算法python实现(适合初学者)

你可能感兴趣的:(优化算法)