• python遗传算法求函数极值
• python遗传算法求解函数极值问题
• 今天小编就为大家分享一篇python 遗传算法求函数极值的实现代码，具有很好的参考价值，希望对大家有所帮助。一起跟随小编过来看看吧
• python语言实现进退法和黄金分割方法求函数极值及所在区间
• 遗传算法实现求函数极大值—Zjh""" import numpy as np import random import matplotlib.pyplot as plt class Ga(): """求出二进制编码的长度""" def __init__...
"""遗传算法实现求函数极大值—Zjh"""
import numpy as np
import random
import matplotlib.pyplot as plt
class Ga():
"""求出二进制编码的长度"""
def __init__(self):
self.boundsbegin = -2
self.boundsend = 3
precision = 0.0001 # 运算精确度
self.Bitlength = int(np.log2((self.boundsend - self.boundsbegin)/precision))+1#%染色体长度
self.popsize = 50# 初始种群大小
self.Generationmax = 12# 最大进化代数
self.pcrossover = 0.90# 交叉概率
self.pmutation = 0.2# 变异概率
self.population=np.random.randint(0,2,size=(self.popsize,self.Bitlength))

"""计算出适应度"""
def fitness(self,population):
Fitvalue=[]
cumsump = []
for i in population:
x=self.transform2to10(i)#二进制对应的十进制
xx=self.boundsbegin + x * (self.boundsend - self.boundsbegin) / (pow(2,self.Bitlength)-1)
s=self.targetfun(xx)
Fitvalue.append(s)
fsum=sum(Fitvalue)
everypopulation=[x/fsum for x in Fitvalue]
cumsump.append(everypopulation[0])
everypopulation.remove(everypopulation[0])
for j in everypopulation:
p=cumsump[-1]+j
cumsump.append(p)
return Fitvalue,cumsump
"""选择两个基因，准备交叉"""
def select(self,cumsump):
seln=[]
for i in range(2):
j = 1
r=np.random.uniform(0,1)
prand =[x-r for x in cumsump]
while prand[j] < 0:
j = j + 1
seln.append(j)
return seln
"""交叉"""
def crossover(self, seln, pc):
d=self.population[seln[1]].copy()
f=self.population[seln[0]].copy()
r=np.random.uniform()
if r<pc:
print('yes')
c=np.random.randint(1,self.Bitlength-1)
print(c)
a=self.population[seln[1]][c:]
b=self.population[seln[0]][c:]
d[c:]=b
f[c:]=a
print(d)
print(f)
g=d
h=f
else:
g=self.population[seln[1]]
h=self.population[seln[0]]
return g,h
"""变异操作"""
def mutation(self,scnew,pmutation):
r=np.random.uniform(0, 1)
if r < pmutation:
v=np.random.randint(0,self.Bitlength)
scnew[v]=abs(scnew[v]-1)
else:
scnew=scnew
return scnew

"""二进制转换为十进制"""
def transform2to10(self,population):
#x=population[-1]  #最后一位的值
x=0
#n=len(population)
n=self.Bitlength
p=population.copy()
p=p.tolist()
p.reverse()
for j in range(n):
x=x+p[j]*pow(2,j)
return x  #返回十进制的数
"""目标函数"""
def targetfun(self,x):
#y = x∗(np.sin(10∗(np.pi)∗x))+ 2
y=x*(np.sin(10*np.pi*x))+2
return y

if __name__ == '__main__':
Generationmax=12
gg=Ga()
scnew=[]
ymax=[]
#print(gg.population)
Fitvalue, cumsump=gg.fitness(gg.population)
Generation = 1
while Generation < Generationmax +1:
Fitvalue, cumsump = gg.fitness(gg.population)
for j in range(0,gg.popsize,2):
seln = gg.select( cumsump)  #返回选中的2个个体的序号
scro = gg.crossover(seln, gg.pcrossover)  #返回两条染色体
s1=gg.mutation(scro[0],gg.pmutation)
s2=gg.mutation(scro[1],gg.pmutation)
scnew.append(s1)
scnew.append(s2)
gg.population = scnew
Fitvalue, cumsump = gg.fitness(gg.population)
fmax=max(Fitvalue)
d=Fitvalue.index(fmax)
ymax.append(fmax)
x = gg.transform2to10(gg.population[d])
xx = gg.boundsbegin + x * (gg.boundsend - gg.boundsbegin) / (pow(2, gg.Bitlength) - 1)
Generation = Generation + 1
Bestpopulation = xx
Targetmax = gg.targetfun(xx)
print(xx)
print(Targetmax)

x=np.linspace(-2,3,30)
y=x*(np.sin(10*np.pi*x))+2
plt.scatter(2.65,4.65,c='red')
plt.xlim(0,5)
plt.ylim(0,6)
plt.plot(x,y)
plt.annotate('local max', xy=(2.7,4.8), xytext=(3.6, 5.2),arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()一个函数求极值的仿真的作业，参考了别人的matlab代码，用python复现了一遍，加深印象！
展开全文
• 基本思想 遗传算法(Genetic Algorithm, GA) 顾名思义是模仿生物的遗传学机理进行计算模拟最优解的过程。 将生物种群特征与问题进行对应 一个染色体代表问题的一个解（一个染色体含有...最后一个是结果 代码 python代码
基本思想
遗传算法(Genetic Algorithm, GA)
顾名思义是模仿生物的遗传学机理进行计算模拟最优解的过程。
将生物种群特征与问题进行对应
一个染色体代表问题的一个解（一个染色体含有多个基因）
一个基因代表问题的一个决策变量
多个个体构成一个种群，多组解构成解的种群。
我们使问题解的种群不断的优胜劣汰，像自然界的自然选择一般，直到最后剩下一个获胜的最优解，便结束了问题的求解。
算法流程
1. 初始化
随机生成一个种群。其中基因需要编码。
常用的编码方式有二进制编码法，浮点编码法，符号编码法。
今天先来做个二进制编码法，其解码、编码、交叉、变异等操作简单易行，但是由于随机性，局部搜索能力较差。
“与人类的染色体不同，我们假设只有“0”和“1”两种碱基，因此只需要将我们的决策变量进行二进制编码即可获得基因序列。”
2. 评估个体适应度
可以直接用函数值作为适应度，我们要找最小值嘛。
3. 进行自然选择

计算出适应度综合$\Sigma f_i$
计算出相对适应度大小$f_i/\Sigma f_i$
产生随机出，确定各个个体被选中的次数

4. 进行组合交叉
选定一个交配概率pc

群体随机配对
随机设定交叉点
互换染色体部分基因

5. 进行变异

随机产生变异点
根据变异概率阈值pm使原有基因突变

终止条件
可以设置若干迭代次数作为终止条件。
目标问题
emmm，是在csdn的必问上看到一个问题，要求寻找目标函数的全局最小值

就打算拿这个试一下
算法实现
初始化
首先初始化种群，如果是n维输入的话，每个染色体上都应该有n个基因，分别代表$x_1.....x_n$
这个时候需要先考虑一些如何进行二进制编码。
x的范围是-32.77到32.77，我选用13位二进制数来编码。
将一个二进制串代表的二进制数转化为十进制数：
$(b_0......b_n)=(\Sigma^n_{i=0}b_i2^i)=x'$
对应区间内的实数：
$x = - 32.77 + x'\frac{65.54}{2^{13}-1}$
那么有还原的函数
def translation(L):#将二进制编码还原为变量
n = 0
for i in range(13):
n += L[i]*pow(2,i)

return -32.77 + n * (65.54/k)

适应度函数与自然选择
这里用比较简单的选择方法，每个个体被选中的概率都是自身的适应度除以总适应度的和。
$\alpha_i = \frac{F_i}{\Sigma F}$
直接使用我们的目标函数，emmm好像不太成，这样的话越小的值适应度越小了，理论上应该是适应度越大才对。
def f(x):#目标函数
n = len(x)
return -20*np.exp(-0.2*np.sqrt(1/n*sum(np.power(x,2))))\
-np.exp(1/n*sum(np.cos(2*pi*x))) + 20

不过那也好说，我们可以找出来所有个体的最大值，然后用这个值减去各个个体的函数值作为其适应度，这样最大的一个的适应度就是0，自然死亡。
def fitness(popular):
fit = [0] * len(popular)
n = len(popular[0])//13 #数据维度
maxfit = -1e5
for i in range(popular):
x = []
for j in range(n):
x.append(translation(i[j:j+13]))
fit[i] = f(np.array(x))
if fit[i] > maxfit:
maxfit = fit[i]
for i in range(len(fit)):
fit[i] = maxfit - fit[i]
return fit

接下来就是轮盘赌了，计算出所有的适应度然后根据概率判断新的种群中的个体

def choose(popular):#进行自然选择
popular_len = len(popular)#个体个数
survival_rate = []
for i in range(popular_len):
survival_rate.append(random.random())

fit = fitness(popular)#每个个体的存活率
best_individual = popular[fit.index(max(fit))]#保存下当前种群最优个体（其实写这里不太会）
survival_rate.sort()
fitin = 0
newin = 0
newpopular = popular

# 开始轮盘赌
# 结束之后，适应度更高的个体在新种群中应该更多
while newin < popular_len:
if survival_rate[newin] < fit[fitin]:
newpopular[newin] = popular[fitin]
newin += 1#旋转轮盘
else:
fitin += 1#旋转轮盘
popular = newpopular
return best_individual

交叉
取交叉率pc=0.5
def crossover(popular,pc):#pc为交叉率
popular_len=len(popular)

for i in range(popular_len-1):
crosspoint = random.randint(0,len(popular[0]))#随机生成交叉点
# 一个个体染色体长度为len(popular[0])，crosspoint为交换位置
#接下来我们让第i个个体和第i+1个个体发生交叉
t1 =[]
t2= []
t1.extend(popular[i][0:crosspoint])#i的前半段
t1.extend(popular[i+1][crosspoint:-1])#i+1的后半段
t2.extend(popular[i+1][0:crosspoint])#i+1的前半段
t2.extend(popular[i][crosspoint:-1])#i的后半段
# 放回种群
popular[i] = t1
popular[i+1] = t2

变异
取变异率0.01吧
def mutation(popular,pm):#pm为变异率
popular_len=len(popular)
chromosome_len = len(popular[0])
for i in range(popular_len):
if random.random()>pm:#大于阈值则发生变异
mutation_point = random.randint(0,chromosome_len-1)
#发生变异
if popular[i][mutation_point] == 1:
popular[i][mutation_point] = 0
else:
popular[i][mutation_point] = 1
、

最后连起来实现迭代
def GA(n):
## 初始化种群
popular_size = 100#种群大小
chromosome_length = n*13#染色体大小
popular = []
for i in range(popular_size):
individual = []
for j in range(chromosome_length):#生成随机基因
individual.append(random.randint(0,1))
popular.append(individual)#向种群添加一个个体
# 种群初始化完成
best_individual = []
for i in range(200):#迭代200次
best_individual.append( choose(popular) ) #保存下最优个体
crossover(popular,0.5)
mutation(popular,0.01)
solutions = []#解的迭代过程
for i in best_individual:
s = []
for j in range(n):
s.append(translation( i[13*j:13*j+13] ))
#还原为了十进制数
solutions.append(s)
return solutions#保存的是各次迭代发现的最优解，最后一个是结果


代码
python代码


展开全文
• 求函数二维函数A在某区间的最大值 A=( 6 - 2×l + l×cos(θ) ) × l×sin(θ) l∈（0,3） θ∈（0，π/2） 此处的搜索优化方法采用黄金分割法，且先后对两个未知量进行黄金搜索。 那么我们在同一个循环中，先固定l...
二维搜索，也就是优化两个未知变量，通常将二维搜索转化为一维搜索进行求解。
例题
二维搜索转一维——黄金分割
求函数二维函数A在某区间的最大值
A=( 6 - 2×l + l×cos(θ) ) × l×sin(θ)
l∈（0,3）
θ∈（0，π/2）
此处的搜索优化方法采用黄金分割法，且先后对两个未知量进行黄金搜索。
那么我们在同一个循环中，先固定l，对θ进行黄金分割搜索，然后固定θ，对l进行黄金分割搜索。
代码如下：
from sympy import *

a = 0  #角度区间下限
b = 90  #角度区间上限
c = 0  #长度区间下限
d = 3  #长度区间上限
dx = 0.05  #迭代精度

def func(x,l):
A = (6 - 2*l + l*cos(x*pi.evalf()/180)) * l*sin(x*pi.evalf()/180)
return A

i = 0
while True:
i += 1
x1 = b - 0.618*(b-a)
x2 = a + 0.618*(b-a)
l1 = d - 0.618*(d-c)
l2 = c + 0.618*(d-c)
if func(x1,l1) > func(x2,l1):
b = x2
elif func(x1,l1) <= func(x2,l1):
a = x1
if func(x1,l1) > func(x1,l2):
d = l2
elif func(x1,l1) <= func(x1,l2):
c = l1
DX = abs(b-a)
LX = abs(d-c)
if DX <= dx and LX <= dx :
print(f'迭代第{i}次,迭代精度小于等于{dx}，最终的搜索区间为：θ∈{min(a, b), max(a, b)}，l∈{min(c, d), max(c, d)}')
print(f'A的最大值：{func((a+b)/2, (c+d)/2)}')
break
else:
pass

结果：
迭代第16次,迭代精度小于等于0.05，最终的搜索区间为：θ∈(59.975536613662115, 60.01628009276722)，l∈(1.999184553788737, 2.000542669758907)
A的最大值：5.19615234282692

如果不会一维黄金分割搜索，请先看我前面写的文章：
用黄金分割法（Golden Section Search Method）求函数最大值的python程序
二维搜索转一维——坐标循环法
coordinate cycling method（坐标循环法），是一种穷举法。
二维搜索求函数极值还有最笨的方法，那就是穷举法。
方法步骤：

此方法耗时耗力，不推荐，仅做了解
还是上面的例题。
代码如下：
from sympy import *

a = 0  #角度区间下限
b = 90  #角度区间上限
c = 0  #长度区间下限
d = 3  #长度区间上限

def func(x,l):
A = (6 - 2*l + l*cos(x*pi.evalf()/180)) * l*sin(x*pi.evalf()/180)
return A

A_list=[0,0,0]

x=0
for angle in (0,90):
while x < angle+1:
x = x + 1/100  #精度为0.01
l = 0
for length in (0,3):
while l < length+1:
l = l + 1/ 100  #精度为0.01
if func(x,l) > A_list[-1]:
A_list[-1] = func(x,l)
A_list[0] = x
A_list[1] = l
#print(A_list)
else:
pass
print(f'A的最大值为：{A_list[-1]}')
print(f'θ={A_list[0]},l={A_list[1]}')

结果：
A的最大值为：5.19615242270663
θ=59.99999999999663,l=2.0000000000000013



展开全文
• 梯度下降法 梯度下降法的基本思想可以类比为一个下山的过程。 假设这样一个场景：一个人被困在山上，需要从山上下来(找到山的最低点，也就是山谷)。但此时山上的浓雾很大，导致...首先，我们有一个可微分的函数。这个
• python实现GA遗传算法求函数（一元函数和二元函数）最大值和最小值.
• 遗传算法求三元函数极值(python)-采用实数编码 本文的遗传算法采用实数编码求三元函数极值求函数为  其完整代码如下： x1x1-x1x2+x3 import numpy as np import random DNA_SIZE =1 POP_SIZE =100 CROSSOVER_...
遗传算法求三元函数极值(python)-采用实数编码

想看二进制编码编码的博客地址在这
遗传算法求三元函数极值(python)-采用二进制编码
本文的遗传算法采用实数编码求三元函数极值
所求函数为

其完整代码如下：
x1x1-x1x2+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=xx-xy+z
‘’’
for index in range(len(val)):
  if val[index] <0.2:
val[index]=0.2
'''

print(val.shape) #(100,) 100 <class ‘numpy.ndarray’>
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_point0:
child[mutate_point] =np.random.uniform(3.0,5.0)
elif mutate_point1:
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(行列 矩阵) <class ‘numpy.ndarray’>
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)) #<class ‘numpy.ndarray’> 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)#<class ‘numpy.ndarray’> (100, 3) 2 300 float64
fitness = get_fitness(pop)
# print(fitness) #<class ‘numpy.ndarray’> (100,) 一维数组 100
pop = select(pop, fitness) #选择生成新的种群
# print(pop.shape) (100,3)
print_info(pop)

`
展开全文
• 人工智能与机器学习——梯度下降法求函数极值一、原理介绍1. 梯度下降法的原理2. 梯度下降法求解过程3. 牛顿法原理4. 牛顿法方法说明二、用Excel完成函数极值的求解1. 求解函数题目2. 用excel计算① ∂z/∂x1 计算...
• 这个代码是在三元函数求极值上的代码上改写的，如果你看了我遗传算法三元函数的代码，你就不用下了，代码大部分不变，改的不多，你基本自己就能改出来了。
• 遗传算法求三元函数极值(python)-采用二进制编码 本文的遗传算法采用二进制编码求三元函数极值求函数为 要想使用遗传算法，首要任务是进行编码 传统的 GA 中, DNA 我们能用一串二进制来表示, 比如: DNA1 = [1...

...

python 订阅