遗传算法求解一元函数二元函数最值

##——————————————————————————施工中————————————————————————————##

import random
import math
import numpy
#于2020.10.16日写,本程序为老师布置的遗传算法的练习#design by zqh#联系方式QQ962903415,博客园-https://www.cnblogs.com/zqh962903415
#——————————————参数部分————————————————#
mainui='''
design by zqh
遗传算法求解函数在实数域的最小值
选择函数的类型
1.一元函数
2.二元函数
3.更改种群规模和迭代世代数
种群规模默认15,世代数100
'''
firstui='''
design by zqh
请输入初代自变量的区间(请输入正数或者负数)
本区间选的离最优值越接近
得到最优值的速度越快越准确

'''
secondui='''
___请输入公式___
注意:自变量用i表示
注意:乘号用*表示,加号用+表示,减号用-表示
注意:sin函数用math.sin()表示,cos函数用math.cos()表示
注意:e用exp()表示
注意:ln(10)用math.log(10,math.e)表示
'''

secondui2='''
___请输入公式___
自变量用x和y表示
注意:乘号用*表示,加号用+表示,减号用-表示
注意:sin函数用math.sin()表示,cos函数用math.cos()表示
注意:e用math.exp()表示
注意:ln(10)用math.log(10,math.e)表示
'''

populationsize=14 #种群尺寸
popgeneration=100 #程序执行的世代数
basedig=[] #存放每代的最优良的那一个单体,用于制图
fitvalue=[] #存放每代的最优良的单体的适应度值,用于制图

#——————————————(产生种群)的模块————————————————#


def createPop(popsize):
ret=[]
for i in range(0,popsize):
num=round(random.uniform(int(sectionleft), int(sectionright)),3)
ret.append(num)
return ret

def createPop2(popsize):
ret=[]
for i in range(0,popsize):
num=round(random.uniform(int(xsectionleft), int(xsectionright)),3)
ret.append(num)
return ret

def createPop3(popsize):
ret=[]
for i in range(0,popsize):
num=round(random.uniform(int(ysectionleft), int(ysectionright)),3)
ret.append(num)
return ret
#——————————————交叉的模块————————————————#
def crossOver(population):
ret=[]
for i in range(0,len(population)):
target=0
x1=round(random.choice(population),3)
# while target!=1:
x2=round(random.choice(population),3)
# if x2!=x1:
# target=1
# if x2==x1:
# continue
ret.append(round((x1+x2)/2,3))
# print('随机选两个%s和%s,求和除以2后%s' %(x1,x2,round((x1+x2)/2,3)))
return ret

#——————————————变异的模块————————————————#
def mutation(population):
newpop=[]
expect=0
for i in population:
expect=expect+i
expect=round(expect/len(population),3)
# print('求得数学期望',expect)
for i1 in population:
vari=random.uniform(expect-3,expect+3)
# print('从(miu-3sigma),(miu+3sigma)取任意自变量',vari)
switch=random.choice(['a','b'])
if switch=='a':
nor_distru = (1 / pow(2 * math.pi, 1 / 2)) * math.exp(-1*pow((vari-expect),2)/2)
if switch=='b':
nor_distru =-1* (1 / pow(2 * math.pi, 1 / 2)) * math.exp(-1 * pow((vari - expect), 2) / 2)
# print('自变量带入高斯分布函数得到扰动',nor_distru)
count=i1+nor_distru
newpop.append(round(count,3))
# print('高斯扰动后的(变异)新种群',newpop)
return newpop


#——————————————自写的排序公式————————————————#
# def paixu(poplist):
# ret=[]
# while(poplist !=[]):
# minkey=poplist[0]
# for i in poplist:
# if minkey>i:
# minkey=i
# if minkey<i:
# minkey=minkey
# ret.append(minkey)
# position=poplist.index(minkey)
# del poplist[position]
# return ret

#——————————————选择函数的公式————————————————#
def fx(poplist,gongshi):
ret = []
for i in poplist:
res = eval(gongshi)
ret.append(round(res,5))
return ret

def fx2(poplist,poplist2,gongshi):
xkey = []
ykey=[]
final=[]
ret=[]
for x in poplist:
for y in poplist2:
res = eval(gongshi)
xkey.append(x)
ykey.append(y)
final.append(round(res,5))
ret.append(xkey)
ret.append(ykey)
ret.append(final)
return ret

#——————————————适应度选择函数————————————————#
def popChoice(population):
dict1={}
ret1=[]
ret=[]
popfit=[]
unionpop=list(set(a).union(set(population)))
# print('新老种群并集',unionpop)
popfit=fx(unionpop,gongshi)
# print('将并集求适应度函数值',popfit)
for xp in range(0,len(unionpop)):
dict1.update({popfit[xp]:unionpop[xp]})
print(dict1)
popfit.sort()
unionpop =popfit
# print('将其从小到大排列',unionpop)
for i1 in range(len(population)):
ret1.append(unionpop[i1])
# print('只取前面popsize个',ret1)
for xp1 in ret1:
ret.append(dict1[xp1])
print('新种群',ret)
print('本代最优单体为%s,它的适应度为%s' %(ret[0],ret1[0]))
print('#------结果——————#')
print('最小值处的自变量为%s,取得fx的最小值为%s' % (ret[0],ret1[0]))
print('#------结果——————#')
fitvalue.append(ret1[0])
basedig.append(ret[0])
return ret

def popChoice2(population,population2):
dict1={}
xpop=[]
ypop=[]
ret1=[]
ret=[]
popfit=[]
unionpop=list(set(a).union(set(population)))
# print('新老种群并集',unionpop)
unionpop2=list(set(a1).union(set(population2)))
# print('新老种群并集',unionpop2)
popfit=fx2(unionpop,unionpop2,gongshi)
# print('将并集求适应度函数值',popfit[2])
for xp in range(0, len(popfit[2])):
dict1.update({popfit[2][xp]: [popfit[0][xp],popfit[1][xp]]})
print(dict1)
popfit=popfit[2]
popfit.sort()
unionpop =popfit
# print('将其适应度函数值从小到大排列',unionpop)
for i1 in range(len(population)):
ret1.append(unionpop[i1])
# print('只取前面popsize个',ret1)
for xp1 in ret1:
ret.append(dict1[xp1])
xpop.append(dict1[xp1][0])
ypop.append(dict1[xp1][1])
print('新种群',ret)
print('本代最优单体为%s,它的适应度为%s' %(ret[0],ret1[0]))
print('#------结果——————#')
print('最小值处的自变量为%s,取得fx的最小值为%s' % (ret[0],ret1[0]))
print('#------结果——————#')
ret.clear()
ret.append(xpop)
ret.append(ypop)
return ret
#——————————————函数主体————————————————#

while 1:
print(mainui)
xuhao=input('请输入操作序号并按下回车')
try:
if xuhao=='1':
print(firstui)
sectionleft=input('初代区间左端>>>>')
sectionright=input('初代区间右端>>>>')
print(secondui)
gongshi=input('>>>>')
start=createPop(populationsize)
print('初始种群', start)
a = start
for i in range(0,popgeneration):
b=crossOver(a)
print('交叉后的新种群',b)
c=mutation(b)
print('变异后的新种群',c)
d=popChoice(c)
a=d
if xuhao=='2':
print(firstui)
xsectionleft=input('x初代区间左端>>>>')
xsectionright=input('x初代区间右端>>>>')
ysectionleft=input('y初代区间左端>>>>')
ysectionright=input('y初代区间右端>>>>')
print(secondui2)
gongshi=input('>>>>')
start=createPop2(populationsize)
print('初始种群', start)
a = start
start1=createPop3(populationsize)
print('初始种群', start1)
a1= start1
for i in range(0,popgeneration):
c=mutation(a)
c1=mutation(a1)
print('变异后的新种群',c)
print('变异后的新种群',c1)
d=popChoice2(c,c1)
a=d[0]
a1=d[1]
if xuhao == '3':
tp1 = input('请输入种群尺寸') # 种群尺寸
tp2 = input('请输入世代数') # 程序执行的世代数
if tp1.isdigit()==False or tp2.isdigit()==False:
print('种群尺寸和世代数只能输入数字')
else:
populationsize =int(tp1) # 种群尺寸
popgeneration =int(tp2) # 程序执行的世代数
except Exception as wrong:
print('操作有误,程序重启')
# plt.plot(basedig,fitvalue)
# plt.ylabel('fitness value') #为y轴加注释
# plt.xlabel('best one') #为x轴加注释
# plt.show()
#于2020.10.16日写,本程序为老师布置的遗传算法的练习
# #design by zqh#联系方式QQ962903415,博客园-https://www.cnblogs.com/zqh962903415
posted @ 2020-10-23 19:23  克莱比-Kirby  阅读(726)  评论(0)    收藏  举报