(1+1)-es进化策略python实现

import numpy as np
import matplotlib.pyplot as plt

'''
1+1 ES进化策略
'''
DNA_SIZE = 1  # DNA (real number)
DNA_BOUND = [0, 5]  # solution upper and lower bounds
N_GENERATIONS = 200  # 进化
MUT_STRENGTH = 5.  # 统一定义的变异强度


def F(x): return np.sin(10 * x) * x + np.cos(2 * x) * x  # to find the maximum of this function


# find non-zero fitness for selection
def get_fitness(pred): return pred.flatten()


def make_kid(parent):
    # 无交叉仅变异
    k = parent + MUT_STRENGTH * np.random.randn(DNA_SIZE)  # 根据父代基因信息以及变异强度进行变异
    k = np.clip(k, *DNA_BOUND)  # 控制范围
    return k


def kill_bad(parent, kid):
    global MUT_STRENGTH
    fp = get_fitness(F(parent))[0]  # 计算得分
    fk = get_fitness(F(kid))[0]
    p_target = 1 / 5  # 变异强度的变异规则所定
    if fp < fk:  # kid better than parent
        parent = kid
        ps = 1.  # kid win -> ps = 1 (successful offspring)
    else:
        ps = 0.
    # adjust global mutation strength
    # np.exp(B) : 求e的幂次方、np.sqrt(B):求B的开方
    MUT_STRENGTH *= np.exp(1 / 3 * (ps - p_target) / (1 - p_target))  # 变异强度的变异规则
    print(MUT_STRENGTH)
    return parent


parent = 5 * np.random.rand(DNA_SIZE)  # parent DNA
plt.ion()  # something about plotting
# 在指定的间隔内返回均匀间隔的数字 200个
x = np.linspace(*DNA_BOUND, 200)

for _ in range(N_GENERATIONS):
    # ES part
    kid = make_kid(parent)  # 生孩子
    py, ky = F(parent), F(kid)
    parent = kill_bad(parent, kid)  # 淘汰不好的

    # something about plotting
    plt.cla()
    plt.scatter(parent, py, s=200, lw=0, c='red', alpha=0.5, )
    plt.scatter(kid, ky, s=200, lw=0, c='blue', alpha=0.5)
    plt.text(0, -7, 'Mutation strength=%.2f' % MUT_STRENGTH)
    plt.plot(x, F(x))
    plt.pause(0.05)
print(parent)
plt.ioff()
plt.show()

有问题希望可以提出,多多交流~
已经更新其他相关的进化算法(GA、ES、CMA-ES、EP等)~

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