遗传算法及其应用实现

使用遗传算法求解函数具有最大值的点X

在这里插入图片描述

"""
Visualize Genetic Algorithm to find a maximum point in a function.
"""
import numpy as np
import matplotlib.pyplot as plt

DNA_SIZE = 10  # DNA length
POP_SIZE = 100  # population size
CROSS_RATE = 0.8  # mating probability (DNA crossover)
MUTATION_RATE = 0.003  # mutation probability
N_GENERATIONS = 200  # stop evolution rule
X_BOUND = [0, 5]  # x upper and lower bounds

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

# 适应性函数(一个值域非负、与F有相同极值点的函数)
def get_fitness(pred):
    return pred + 1e-3 - np.min(pred)

# 选择算子(适者生存,不适者遭淘汰)
def select(pop, fitness):
    idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=fitness / fitness.sum())  # 比例选择规则(另外可用“模拟退火算子”)
    return pop[idx]

# 杂交算子(促进进化的主要手段)
def crossover(parent, pop):
    if np.random.rand() < CROSS_RATE:  # 多点杂交(另外还有“单点杂交”、“两点杂交”、“均匀杂交”)
        i_ = np.random.randint(0, POP_SIZE, size=1)  # select another individual from pop
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool)  # choose crossover points
        parent[cross_points] = pop[i_, cross_points]  # mating and produce one child
    return parent

# 变异算子(使算法达到局部极值时有逃离局部极值“陷阱”的可能性)
def mutate(child):
    for point in range(DNA_SIZE):
        if np.random.rand() < MUTATION_RATE:
            child[point] = 1 if child[point] == 0 else 0
    return child

# 将二进制的DNA转换为实数并且标准化到[0, 5]
def translateDNA(pop):
    return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * X_BOUND[1]
# np.arange(5)[::-1] 逆序:[4 3 2 1 0]
# 2 ** np.arange(5)[::-1]  幂次:[16  8  4  2  1]
# pop.dot(2 ** np.arange(5)[::-1])  进制转换:二进制DNA转换为十进制数
# float(2 ** DNA_SIZE - 1) 最大十进制数:31=[16+8+4+2+1]
# pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * X_BOUND[1]  将X范围缩放到:[0, 5]

pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))  # 初始化DNA
# [[1 0 1 1 0 0]
#  [0 1 1 1 0 0]
#  [1 0 0 1 1 1]]
plt.ion()  # something about plotting
x = np.linspace(*X_BOUND, 200)
plt.plot(x, F(x))

for _ in range(N_GENERATIONS):
    F_values = F(translateDNA(pop))  # compute function value by extracting DNA

    # something about plotting
    if 'sca' in globals(): sca.remove()
    sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c='red', alpha=0.5);
    plt.pause(0.05)

    # GA part (evolution)
    fitness = get_fitness(F_values)
    print("Most fitted DNA: ", pop[np.argmax(fitness), :])
    pop = select(pop, fitness)
    pop_copy = pop.copy()
    for parent in pop:
        child = crossover(parent, pop_copy)
        child = mutate(child)
        parent[:] = child  # 自然选择(另外还有“父子混合选择”策略)

print("the X: ", translateDNA(pop[np.argmax(fitness), :]))  # 具有最高点的X值

plt.ioff();
plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值