自然计算遗传算法.docx
《自然计算遗传算法.docx》由会员分享,可在线阅读,更多相关《自然计算遗传算法.docx(14页珍藏版)》请在冰豆网上搜索。
自然计算遗传算法
自然计算大作业
一.二进制编码
在遗传算法中,首先要将数据进行编码,这里采用二进制的方式进行编码。
第一步,我们根据题目的介绍可以得知该函数含有两个变量,以及各自的定义域。
在二进制编码中,我们首先要先计算它的编码长度。
计算公式如下:
$${2^{{m_j}-1}}<({b_j}-{a_j})*precision\le{2^{{m_j}}}-1$$
其中precision为精度,如小数点后5位,则precision=10^5,mj为编码长度,${x_j}\in[{a_j},{b_j}]$
二.二进制解码
解码即编码的逆过程:
$${x_j}={a_j}+{\rm{decimal}}(substrin{g_j})\times\frac{{{b_j}-{a_j}}}{{{2^{{m_j}}}-1}}$$
三.种群初始化
编码完成后,开始对种群初始化,为了简便采用随机地方式进行初始化。
初始群体的生成:
随机产生N个初始串结构数据,每个串结构数据称为一个个体,N个个体构成了一个群体。
GA以这N个串结构数据作为初始点开始进化。
defrand_init(self):
foriinrange(self.code_x1_length):
self.code_x1+=str(random.randint(0,1))
foriinrange(self.code_x2_length):
self.code_x2+=str(random.randint(0,1))
四.适应度评估
适应度表明个体或解的优劣性。
不同的问题,适应度函数的定义方式也不同。
defdecoding(self,code_x1,code_x2):
self.x1=self.bounds[0][0]+int(code_x1,2)*(self.bounds[0][1]-self.bounds[0][0])/(
2**self.code_x1_length-1)
self.x2=self.bounds[1][0]+int(code_x2,2)*(self.bounds[1][1]-self.bounds[1][0])/(
2**self.code_x2_length-1)
五.选择
选择的目的是为了从当前群体中选出优良的个体,使它们有机会作为父代为下一代繁殖子孙。
遗传算法通过选择过程体现这一思想,进行选择的原则是适应度强的个体为下一代贡献一个或多个后代的概率大。
选择体现了达尔文的适者生存原则。
采用轮盘赌方式进行选择,主要思想是适应度高的,被选择到的概率大。
defselect(self):
"""
轮盘赌选择
:
return:
"""
#calculatefitnessfunction
sum_f=0
foriinrange(self.pop_size):
self.pop[i].func()
#guaranteefitness>0
min=self.pop[0].y
foriinrange(self.pop_size):
ifself.pop[i].ymin=self.pop[i].y
ifmin<0:
foriinrange(self.pop_size):
self.pop[i].y=self.pop[i].y+(-1)*min
#roulette
foriinrange(self.pop_size):
sum_f+=self.pop[i].y
p=[0]*self.pop_size
foriinrange(self.pop_size):
p[i]=self.pop[i].y/sum_f
q=[0]*self.pop_size
q[0]=0
foriinrange(self.pop_size):
s=0
forjinrange(0,i+1):
s+=p[j]
q[i]=s
#startroulette
v=[]
foriinrange(self.pop_size):
r=random.random()
ifrv.append(self.pop[0])
forjinrange(1,self.pop_size):
ifq[j-1]v.append(self.pop[j])
self.pop=v
六.交叉
交叉操作是遗传算法中最主要的遗传操作。
通过交叉操作可以得到新一代个体,新个体组合了其父辈个体的特性。
交叉体现了信息交换的思想。
采用单点交叉法。
随机从种群中选两个个体,然后再随机选一个交叉点,交换位置。
defcross(self):
"""
交叉
:
return:
"""
foriinrange(int(self.pop_size/2)):
ifself.pc>random.random():
#randonselect2chromosomesinpops
i=0
j=0
whilei==j:
i=random.randint(0,self.pop_size-1)
j=random.randint(0,self.pop_size-1)
pop_i=self.pop[i]
pop_j=self.pop[j]
#selectcrossindex
pop_1=random.randint(0,pop_i.code_x1_length-1)
pop_2=random.randint(0,pop_i.code_x2_length-1)
#getnewcode
new_pop_i_code1=pop_i.code_x1[0:
pop_1]+pop_j.code_x1[pop_1:
pop_i.code_x1_length]
new_pop_i_code2=pop_i.code_x2[0:
pop_2]+pop_j.code_x2[pop_2:
pop_i.code_x2_length]
new_pop_j_code1=pop_j.code_x1[0:
pop_1]+pop_i.code_x1[pop_1:
pop_i.code_x1_length]
new_pop_j_code2=pop_j.code_x2[0:
pop_2]+pop_i.code_x2[pop_2:
pop_i.code_x2_length]
pop_i.code_x1=new_pop_i_code1
pop_i.code_x2=new_pop_i_code2
pop_j.code_x1=new_pop_j_code1
pop_j.code_x2=new_pop_j_code2
七.变异
变异首先在群体中随机选择一个个体,对于选中的个体以一定的概率随机地改变串结构数据中某个串的的值。
同生物界一样,GA中变异发生的概率很低,通常取值很小。
这里的变异,我们先以变异概率,从种群中选一个,然后对选中的个体,随机选一个变异位点进行变异。
defmutation(self):
"""
变异
:
return:
"""
foriinrange(self.pop_size):
ifself.pm>random.random():
pop=self.pop[i]
#selectmutationindex
index1=random.randint(0,pop.code_x1_length-1)
index2=random.randint(0,pop.code_x2_length-1)
i=pop.code_x1[index1]
i=self.__inverse(i)
pop.code_x1=pop.code_x1[:
index1]+i+pop.code_x1[index1+1:
]
i=pop.code_x2[index2]
i=self.__inverse(i)
pop.code_x2=pop.code_x2[:
index2]+i+pop.code_x2[index2+1:
]
八.目标函数
deffunc(self):
self.decoding(self.code_x1,self.code_x2)
self.y=21.5+self.x1*math.sin(4*math.pi*self.x1)+self.x2*math.sin(20*math.pi*self.x2)
九.算法主流程
遗传的主要框架已经完毕,下面展示主流程,及画图部分代码。
defga(self):
"""
算法主函数
:
return:
"""
self.init_pop()
best=self.find_best()
self.g_best=copy.deepcopy(best)
y=[0]*self.pop_size
foriinrange(self.max_gen):
self.cross()
self.mutation()
self.select()
best=self.find_best()
self.bests[i]=best
ifself.g_best.yself.g_best=copy.deepcopy(best)
y[i]=self.g_best.y
print(self.g_best.y)
#plt
plt.figure
(1)
x=range(self.pop_size)
#plt.axis([0,200,30,40])
#[0,200,30,40]
plt.plot(x,y)
plt.ylabel('functionvalue')
plt.xlabel('generations')
plt.show()
十.结果
附完整程序
importcopy
importrandom
importmatplotlib.pyplotasplt
fromChromosomeimportChromosome
classGeneticAlgorithm:
def__init__(self,bounds,precision,pm,pc,pop_size,max_gen):
"""
算法初始化
:
parambounds:
变量范围
:
paramprecision:
精度
:
parampm:
变异概率
:
parampc:
交叉概率
:
parampop_size:
种群大小
:
parammax_gen:
最大迭代次数
:
return:
"""
self.bounds=bounds
self.precision=precision
self.pm=pm
self.pc=pc
self.pop_size=pop_size
self.max_gen=max_gen
self.pop=[]
self.bests=[0]*max_gen
self.g_best=0
self.bests_val=[0]*max_gen
defga(self):
"""
算法主函数
:
return:
"""
self.init_pop()
best=self.find_best()
self.g_best=copy.deepcopy(best)
y=[0]*self.max_gen
foriinrange(self.max_gen):
self.cross()
self.mutation()
self.select()
best=self.find_best()
self.bests[i]=best
self.bests_val[i]=best.y
ifself.g_best.yself.g_best=copy.deepcopy(best)
y[i]=self.g_best.y
print(self.g_best.y)
#plt
plt.figure
(1)
x=range(self.max_gen)
#plt.axis([0,200,0,40])
#[0,200,0,40]
plt.plot(x,y,'r')
plt.plot(x,self.bests_val,'g')
plt.ylabel('functionvalue')
plt.xlabel('generations')
plt.show()
definit_pop(self):
"""
初始化种群
:
return:
"""
foriinrange(self.pop_size):
chromosome=Chromosome(self.bounds,self.precision)
self.pop.append(chromosome)
defcross(self):
"""
交叉
:
return:
"""
foriinrange(int(self.pop_size/2)):
ifself.pc>random.random():
#randonselect2chromosomesinpops
i=0
j=0
whilei==j:
i=random.randint(0,self.pop_size-1)
j=random.randint(0,self.pop_size-1)
pop_i=self.pop[i]
pop_j=self.pop[j]
#selectcrossindex
pop_1=random.randint(0,pop_i.code_x1_length-1)
pop_2=random.randint(0,pop_i.code_x2_length-1)
#getnewcode
new_pop_i_code1=pop_i.code_x1[0:
pop_1]+pop_j.code_x1[pop_1:
pop_i.code_x1_length]
new_pop_i_code2=pop_i.code_x2[0:
pop_2]+pop_j.code_x2[pop_2:
pop_i.code_x2_length]
new_pop_j_code1=pop_j.code_x1[0:
pop_1]+pop_i.code_x1[pop_1:
pop_i.code_x1_length]
new_pop_j_code2=pop_j.code_x2[0:
pop_2]+pop_i.code_x2[pop_2:
pop_i.code_x2_length]
pop_i.code_x1=new_pop_i_code1
pop_i.code_x2=new_pop_i_code2
pop_j.code_x1=new_pop_j_code1
pop_j.code_x2=new_pop_j_code2
defmutation(self):
"""
变异
:
return:
"""
foriinrange(self.pop_size):
ifself.pm>random.random():
pop=self.pop[i]
#selectmutationindex
index1=random.randint(0,pop.code_x1_length-1)
index2=random.randint(0,pop.code_x2_length-1)
i=pop.code_x1[index1]
i=self.__inverse(i)
pop.code_x1=pop.code_x1[:
index1]+i+pop.code_x1[index1+1:
]
i=pop.code_x2[index2]
i=self.__inverse(i)
pop.code_x2=pop.code_x2[:
index2]+i+pop.code_x2[index2+1:
]
defselect(self):
"""
轮盘赌选择
:
return:
"""
#calculatefitnessfunction
sum_f=0
foriinrange(self.pop_size):
self.pop[i].func()
#guaranteefitness>0
min=self.pop[0].y
foriinrange(self.pop_size):
ifself.pop[i].ymin=self.pop[i].y
ifmin<0:
foriinrange(self.pop_size):
self.pop[i].y=self.pop[i].y+(-1)*min
#roulette
foriinrange(self.pop_size):
sum_f+=self.pop[i].y
p=[0]*self.pop_size
foriinrange(self.pop_size):
p[i]=self.pop[i].y/sum_f
q=[0]*self.pop_size
q[0]=0
foriinrange(self.pop_size):
s=0
forjinrange(0,i+1):
s+=p[j]
q[i]=s
#startroulette
v=[]
foriinrange(self.pop_size):
r=random.random()
ifrv.append(self.pop[0])
forjinrange(1,self.pop_size):
ifq[j-1]v.append(self.pop[j])
self.pop=v
deffind_best(self):
"""
找到当前种群中最好的个体
:
return:
"""
best=copy.deepcopy(self.pop[0])
foriinrange(self.pop_size):
ifbest.ybest=copy.deepcopy(self.pop[i])
returnbest
def__inverse(self,i):
"""
变异时候用的,将1变为0,0变为1
:
parami:
变异位置
:
return:
"""
r='1'
ifi=='1':
r='0'
returnr
if__name__=='__main__':
bounds=[[-3,12.1],[4.1,5.8]]
precision=100000
algorithm=GeneticAlgorithm(bounds,precision,0.01,0.25,500,1000)
algorithm.ga()
pass
importmath
importrandom
classChromosome:
def__init__(self,bounds,precision):
self.x1=1
self.x2=1
self.y=0
self.code_x1=''
self.code_x2=''
self.bounds=bounds
temp1=(bounds[0][1]-bounds[0][0])*precision
self.code_x1_length=math.ceil(math.log(temp1,2))
temp2=(bounds[1][1]-bounds[1][0])*precision
self.code_x2_length=math.ceil(math.log(temp2,2))
self.rand_init()
self.func()
defrand_init(self):
foriinrange(self.code_x1_length):
self.code_x1+=str(random.randint(0,1))
foriinrange(self.code_x2_length):
self.code_x2+=str(random.randint(0,1))
defdecoding(self,code_x1,code_x2):
self.x1=self.bounds[0][0]+int(code_x1,2)*(self.bounds[0][1]-self.bounds[0][0])/(
2**self.code_x1_length-1)
self.x2=self.bounds[1][0]+int(code_x2,2)*(self.bounds[1][1]-self.bounds[1][0])/(
2**self.code_x2_length-1)
deffunc(self):
self.decoding(self.code_x1,self.code_x2)
self.y=21.5+self.x1*math.sin(4*math.pi*self.x1)+self.x2*math.sin(20*math.pi*self.x2)
if__name__=='__main__':
a=[[-3,1],[4,5]]
chromo