10.1.1 使用python完成第一个遗传算法

举例如下:

求函数的在x=[-3,3],y=[-3,3]上的最大值:

【思路】

  1. 把DNA设为:48个bit的数组。 奇数为x, 偶数为y;就是说24个位组成x,24个位组成y。

如何得到x,y: 24个奇数位转换成数值比如b, 则 x = b/(2^24-1)* (3 - (-3)) -3

2.交叉因子:

就是父的前一部分+母DNA的后一部分

  1. 变异因子:

就是某个位取反。

【代码】

代码如下,使用200条DNA,迭代100次,得到结果 (x,y)=(0,1.582), z=8.1. 结果比较稳定。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from jmespath.ast import projection
from matplotlib import  cm
from mpl_toolkits.mplot3d import Axes3D

DNA_SIZE=24
POP_SIZE=200
N_GENERATIONS=100
CROSSOVER_RATE=0.8
MUTATION_RATE=0.005

X_BOUND =[-3,3]
Y_BOUND =[-3,3]
def F(x,y):
    # 2(3-x)^2 e( -x^2 - (y+1)^2) - 4 e(-(x+2)^2-y^2) - 6 e(-(x-2)^2-y(y-2)^2)
    #return   2*(3-x)**2* np.exp(-x**2-(y+1)**2)-4*np.exp(-(x+2)**2-y**2)-6*np.exp(-(x-2)**2-(y-2)**2)
    return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)-10*(x/5-x**3-y**5)*np.exp(-x**2-y**2)-1/2*np.exp(-(x+1)**2-y**2)
    #return 10-x**2-y**2
def plot_3d(ax):
    x = np.linspace(*X_BOUND, 100)
    y = np.linspace(*Y_BOUND, 100)
    X, Y = np.meshgrid(x, y)



    Z = F(X, Y)
    surf = ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap = cm.coolwarm)

    # 添加颜色条
    fig.colorbar(surf, ax=ax, shrink=0.5, aspect=10)

    # 设置坐标轴标签
    ax.set_zlim((-20,20))
    ax.set_xlabel('X轴')
    ax.set_ylabel('Y轴')
    ax.set_zlabel('Z轴')

    # 设置标题
    ax.set_title(':z=f(x,y)')

    plt.pause(3)
    plt.show()

def translateDNA(pop):
    x_pop = pop[:,1::2] #奇数列表示x
    y_pop = pop[:,::2] #偶数列表示y
    x = x_pop.dot(  2** np.arange(DNA_SIZE) [::-1]   )/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+ X_BOUND[0]
    y = y_pop.dot(  2** np.arange(DNA_SIZE) [::-1]   )/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+ Y_BOUND[0]
    return  x,y

def crossover_and_mutaion(pop,Crossover_rate=CROSSOVER_RATE):

    halfpop = int(POP_SIZE/2)
    fitness = get_fitness(pop)
    indices = np.argpartition(fitness, -halfpop)[-halfpop:]  #得到前50%最好的样本进行保留

    new_pop=[]
    #保留原来比较好的50%.
    for pepole in pop[indices]:
        new_pop.append(pepole)

    #其他的进行交叉以及变异
    for father in pop:
        child = father
        if(np.random.rand()<Crossover_rate):
            mother = pop[np.random.randint(POP_SIZE)]
            cross_point=np.random.randint(0,DNA_SIZE*2)
            child[cross_point:]=mother[cross_point:]
        mutation(child) #变异
        new_pop.append(child)
    return new_pop

#编译
def mutation(child,mutation_rate=MUTATION_RATE):
    if np.random.rand()<mutation_rate:
        mutation_point = np.random.randint(0,DNA_SIZE*2)
        child[mutation_point]=  child[mutation_point]^1

#选择
def select(pop,fitness):

    idx = np.random.choice(np.arange(fitness.size),size=POP_SIZE,replace=True,p=(fitness)/fitness.sum())
    return pop[idx]

def get_fitness(pop):
    x,y=translateDNA(pop)
    pred=F(x,y)
    return (pred- np.min(pred))+1e-3

def print_info(pop):
    fitness = get_fitness(pop)
    max_fitness_index= np.argmax(fitness)
    x,y=translateDNA(pop)
    print("最优基因:",pop[max_fitness_index])
    print("(x,y):",(x[max_fitness_index],y[max_fitness_index]))

if __name__ == '__main__':
    # main函数,程序入口
    # 创建数据

    fig = plt.figure(figsize=(12,9))
    ax=fig.add_subplot(111,projection='3d')
    plt.ion()
    plot_3d(ax)

    population = np.random.randint(2,size=(POP_SIZE,DNA_SIZE*2))

    for i in range(N_GENERATIONS):
        x,y=translateDNA(population)

        population = np.array( crossover_and_mutaion(population,Crossover_rate=0.8))

        fitness=get_fitness(population)
        pop = select(population,fitness)
        if i == N_GENERATIONS - 1:
            x1, y1 = translateDNA(pop)
            sca = ax.scatter(x1, y1, F(x1, y1), c='green', marker='*',linewidths=5)
            plt.show()
            plt.pause(0.1)

        print("迭代:",i)
    print(population)
    print_info(population)
    plt.ioff()
    plot_3d(ax)

【附录】

1.np.argpartition可以取数组中最大的k个值的序号;或者最小k个值的序号

最小3个值的序号: np.argpartition(arr, 3)[:3]

最大3个值的序号: np.argpartition(arr, -3)[-3:]

最小值序号举例如下:

arr = np.array([3, 1, 4, 1, 5, 9, 2, 6]) ---> [3, 1, 4, 1, 5, 9, 2, 6]

indices = np.argpartition(arr, 3) ---> [1 3 6 0 2 4 7 5]

np.argpartition(arr, 3)[:3] -----> array([1, 3, 6])

最大值序号举例如下:

np.argpartition(arr, -3)[-3:] ----> array([4, 7, 5])

2.np.random.choice(a),从数组中选择,可指定概率,可放回/不放回

复制代码
np.random.choice(a, size=None, replace=True, p=None)
参数 说明 默认值
a 输入数组或整数 必需
size 输出形状 None
replace 是否允许重复抽样 True
p 每个元素的概率分布 None

np.random.choice(data,7,replace=False) --》 array([5, 6, 3, 2, 9, 0, 4])

np.random.choice(data,7,replace=True) -》array([6, 4, 6, 9, 1, 7, 6])

data = np.arange(5) ---》 array([0, 1, 2, 3, 4])

p=[0.1,0.1,0.2,0.3,0.3]

np.random.choice(data, size=8, p=p) ----》 array([3, 1, 4, 4, 2, 1, 4, 3])

相关推荐
青春不败 177-3266-05202 个月前
MATLAB近红外光谱分析技术及实践技术应用
随机森林·机器学习·支持向量机·matlab·卷积神经网络·遗传算法·近红外光谱
禺垣3 个月前
遗传算法的原理与实现示例
遗传算法·优化算法
软件算法开发4 个月前
基于自适应交叉概率和变异概率遗传算法的地铁车辆使用寿命和璇修次数优化matlab仿真
matlab·遗传算法·自适应交叉概率·自适应变异概率·璇修次数·使用寿命
__lost5 个月前
MATLAB退火算法和遗传算法解决旅行商问题
开发语言·算法·matlab·遗传算法·退火算法
盼小辉丶7 个月前
遗传算法与深度学习实战(37)——NEAT初体验
人工智能·深度学习·遗传算法
青云交7 个月前
Java 大视界 -- Java 大数据在智慧交通信号灯智能控制中的应用(116)
java·大数据·遗传算法·智慧交通·实时数据处理·信号灯智能控制·多源数据融合
我爱C编程8 个月前
基于遗传算法的64QAM星座图的最优概率整形matlab仿真,对比优化前后整形星座图和误码率
matlab·遗传算法·64qam·最优概率整形
盼小辉丶9 个月前
遗传算法与深度学习实战(29)——编码卷积自编码器架构
人工智能·深度学习·遗传算法
盼小辉丶10 个月前
遗传算法与深度学习实战(26)——编码卷积神经网络架构
深度学习·cnn·遗传算法