举例如下:
求函数的在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的后一部分
3. 变异因子:
就是某个位取反。
【代码】
代码如下,使用200条DNA,迭代100次,得到结果 (x,y)=(0,1.582), z=8.1. 结果比较稳定。
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()
【附录】
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])