遗传算法求二元函数极值怎么编码_三元函数极值的遗传算法(Python)-实数编码,求,python,采用...

使用遗传算法并采用实数编码,通过Python实现求解三元函数极值问题。文章包含函数定义、种群初始化、交叉变异操作以及适应度选择等关键步骤。
摘要由CSDN通过智能技术生成

遗传算法求三元函数极值(python)-采用实数编码

想看二进制编码编码的博客地址在这

遗传算法求三元函数极值(python)-采用二进制编码

本文的遗传算法采用实数编码求三元函数极值

所求函数为

866fc7ee147a373ffa6765eacd692bf2.png

`

其完整代码如下:

x1

x1-x1

x2+x3

import numpy as np

import random

DNA_SIZE =1

POP_SIZE =100

CROSSOVER_RATE = 0.8

MUTATION_RATE = 0.015

N_GENERATIONS = 500

X_BOUND = [3.0,5.0]#x1

Y_BOUND = [2.1,6.7]#x2

Z_BOUND = [1.2,9.6]#x3

def F(x, y,z):

val=x

x-x

y+z

‘’’

for index in range(len(val)):

if val[index] <0.2:

val[index]=0.2

'''

print(val.shape) #(100,) 100

return val

def get_fitness(pop):

x,y ,z= translateDNA(pop)

pred = F(x, y,z)

return pred

def translateDNA(pop): #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目

# x_pop = pop[:,0:DNA_SIZE]#这样的写法shape 是(3, 1) 3行1列 ndim维度是2(行,列 矩阵 )

# 也可以认为是二维数组,有3行,每行有1个元素 size为3 [[3.18796615]\n [3.32110516]\n [4.34665405]]

‘’'因为这样写x_pop = pop[:, 0:DNA_SIZE] shape是(3,1)是二维数组,所以会报"对象太深,无法容纳所需的数组"的错误,

第一种解决方法是进行reshape,比如reshape(3,)即变成了一维数组,元素个数是3个,即语法是x_pop=pop[:,0:DNA_SIZE].reshape(POP_SIZE,)

这时x_pop就变为[4.96893731 3.24515899 3.51500566] 一维数组

第二种方法是在矩阵(二维数组)pop中直接选择某一列元素,比如 pop[:, 0],表示选择pop第0列所有的元素

'''

x_pop = pop[:, 0] # 取前DNA_SIZE个列表示x 这样的写法shape是(3,) ndim维度是1 一维数组 ,数组元素有3个 size为3 [4.28040552 3.25412449 4.61336022]

# print(x_pop.shape)

y_pop = pop[:,1]#取中间DNA_SIZE个列表示y

z_pop = pop[:,2]#取后DNA_SIZE个列表示z

# print(x_pop)

'''pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)'''#二进制--->十进制

# 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]

# z = z_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Z_BOUND[1]-Z_BOUND[0])+Z_BOUND[0]

# print(x,z)

return x_pop,y_pop,z_pop

def mutation(child, MUTATION_RATE=0.003):

if np.random.rand() < MUTATION_RATE: #以MUTATION_RATE的概率进行变异

mutate_point = np.random.randint(0, DNA_SIZE*3)#随机产生一个实数,代表要变异基因的位置

if mutate_point

0:

child[mutate_point] =np.random.uniform(3.0,5.0)

elif mutate_point

1:

child[mutate_point] =np.random.uniform(2.1,6.7)

else:

child[mutate_point] =np.random.uniform(1.2,9.6)

def crossover_and_mutation(pop, CROSSOVER_RATE = 0.015):

new_pop = []

for father in pop:#遍历种群中的每一个个体,将该个体作为父亲

child = father#孩子先得到父亲的全部基因

if np.random.rand() < CROSSOVER_RATE:#产生子代时不是必然发生交叉,而是以一定的概率发生交叉

mother = pop[np.random.randint(POP_SIZE)]#再种群中选择另一个个体,并将该个体作为母亲

cross_points = np.random.randint(low=0, high=DNA_SIZE*3)#随机产生交叉的点

child[cross_points:] = mother[cross_points:]#孩子得到位于交叉点后的母亲的基因

mutation(child)#mutation(child,MUTATION_RATE)每个后代有一定的机率发生变异

new_pop.append(child)

return new_pop

def select(pop, fitness): # nature selection wrt pop’s fitness

# fitnew=fitness.copy() #浅拷贝

fitnew = fitness

# for index in range(len(fitnew)):

# if fitnew[index] <0:

# fitnew[index]=0

fitnew=fitnew + 1e-3 - np.min(fitnew)

p=(fitnew)/(fitnew.sum())

# print(fitnew)

# print(fitnew.sum())

# print(np.arange(POP_SIZE)) #0,1,2,3,...,99

idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE,replace=True,p=p)

# print(pop[idx].shape) #shape (3, 3)

'''

[[3.43993966 5.19547684 5.17821964]

[4.0803077 5.19547684 5.17821964]

[3.43993966 5.19547684 5.17821964]]

'''

return pop[idx] #尽量选择适应值高的函数值的个体

‘’’

如果POP_SIZE=3,即种群个数是3,则从交叉,变异后的种群中,选择3个适应值高 pop[idx]=[2 0 0]的新个体去

更新pop种群,之后再进行不断的迭代,直到达到迭代次数终止。

‘’’

def print_info(pop):

fitness = get_fitness(pop)

max_fitness_index = np.argmax(fitness)

print(“max_fitness:”, fitness[max_fitness_index])

x,y,z = translateDNA(pop)

print("最优的基因型:", pop[max_fitness_index])

print("(x, y, z):", (x[max_fitness_index], y[max_fitness_index],z[max_fitness_index]))

if

name

== “

main

”:

pop1 = np.random.uniform(3.0,5.0, size=(POP_SIZE, DNA_SIZE)) #matrix (POP_SIZE, DNA_SIZE)

pop2 = np.random.uniform(2.1, 6.7, size=(POP_SIZE, DNA_SIZE))

pop3 = np.random.uniform(1.2, 9.6, size=(POP_SIZE, DNA_SIZE))

print(type(pop1))# (100,1) 维度是2(行列 矩阵)

pop={pop1,pop2,pop3}

pop=np.hstack((pop1,pop2,pop3))

print(pop)

‘’’

[[3.44603448 4.51707625 7.90178727]

[4.57616299 5.11309286 4.86911781]

[3.24273815 2.9253602 4.45149325]

[4.39321276 3.1657492 5.16654786]]

‘’’

print(type(pop)) # n维数组

print(pop.shape) #(100,3) 矩阵有 100行,3列

print(pop.ndim) # 2 因为矩阵有行和列两个维度

print(pop.size) #300 矩阵共有300个元素

print(pop.dtype) #float64 矩阵元素类型是float64

for _ in range(N_GENERATIONS):#迭代N代

x,y,z = translateDNA(pop) #这句代码,我觉得没啥作用

# print(x) #(100,) [4.82264692 4.04610252 4.92107325 4.49556859 3.1322498 3.60757363…] 一维数组100个数据

pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))

# print(pop.dtype)# (100, 3) 2 300 float64

fitness = get_fitness(pop)

# print(fitness) # (100,) 一维数组 100

pop = select(pop, fitness) #选择生成新的种群

# print(pop.shape) (100,3)

print_info(pop)

`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值