遗传算法实现寻找函数最值

遗传算法的原理参考维基百科:https://zh.wikipedia.org/wiki/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95

遗传算法流程图:

遗传算法实现寻找函数最值_第1张图片

遗传算法的思想和流程都是很简单的,但是运用在具体应用时却会常常无从下手。如何编码解码,如何进行交叉是两个难点。

遗传算法的最简单例子——寻找函数f(x)=x+5sin(5x)+2cos(4x)在区间[0,10]上的函数最值。

函数图像:

遗传算法实现寻找函数最值_第2张图片

种群规模count=20,染色体长度length=18,进化次数itter_time=10

编码策略是:染色体长度length=18,有2^18个不同组合。那么如何将2^18个不同组合对应到区间[0,10]上呢?

此时对应的解码策略是:V=start+x*(end-start)/(2^length-1),这里start表示区间下限,在此例中即为0;end表示区间上限,在此例中即为10;x为2进制编码的数值;V为解码值,即染色体的真实值;length为染色体长度。

对应代码:

#解码
def decode(x):
    y=start+x*(end-start) / (2**length-1)
    return y

交叉策略:采用最简单的点交叉策略。

对于两个不同的染色体Xu和Xv,随机得到一个点交叉位置序号mask,mask为(0,length)上的随机整数。

两条染色体进行交叉:

Xu=Xu[0至mask]片段上的基因+Xv[mask至length]片段上的基因

Xv=Xv[0至mask]片段上的基因+Xu[mask至length]片段上的基因

对应代码:

#交叉繁殖
def crossover(parents):
    #生成子代的个数,以此保证种群稳定
    target_count=count-len(parents)
    #孩子列表
    children=[]
    while len(children)

全部代码:

import numpy as np
import matplotlib.pyplot as plt
import math
import random
# x=np.linspace(-10,10,100)
#
# y=x + 10*np.sin(5*x) + 7*np.cos(4*x)

#GA参数
#查找范围
start=0
end=10

#染色体长度
length=18

#种群数
count=20

#进化次数
itter_time=10

#设置强者的定义概率,即种群前30%为强者
retain_rate=0.3

#设置弱者的存活概率
random_select_rate=0.5

#变异率
mutation_rate=0.2


#目标函数
def aimFunction(x):
    y=x+5*math.sin(5*x)+2*math.cos(4*x)
    return y

#解码
def decode(x):
    y=start+x*(end-start) / (2**length-1)
    return y

#获取随机个体,用于生成种群
def gen_chromosome():
    """
    随机生成长度为length的染色体,每个基因的取值是0或1
    这里用一个bit表示一个基因
    """
    chromosome = 0
    for i in range(length):
        chromosome |= (1 << i) * random.randint(0, 1)
    return chromosome

#自然选择
def selection(population):
    """
    选择
    先对适应度从大到小排序,选出存活的染色体
    再进行随机选择,选出适应度虽然小,但是幸存下来的个体
    """
    # 对适应度从大到小进行排序
    graded = [(aimFunction(decode(chromosome)), chromosome) for chromosome in population]
    graded = [x[1] for x in sorted(graded, reverse=True)]
    # 选出适应性强的染色体
    retain_length = int(len(graded) * retain_rate)
    parents = graded[:retain_length]
    # 选出适应性不强,但是幸存的染色体
    for chromosome in graded[retain_length:]:
        if random.random() < random_select_rate:
            parents.append(chromosome)
    return parents

#交叉繁殖
def crossover(parents):
    #生成子代的个数,以此保证种群稳定
    target_count=count-len(parents)
    #孩子列表
    children=[]
    while len(children)

 

 

你可能感兴趣的:(启发式算法)