Python遗传算法工厂模式封装实现
Python遗传算法工厂模式封装实现
本文提供一个使用工厂模式封装Python遗传算法的示例,并对其进行了SEO优化。该算法使用轮盘赌选择、交叉和变异操作,用于解决一个简单的优化问题。
import math
import random
import time
import copy
# 工厂类
class GeneticAlgorithm:
def __init__(self):
self.PI = 3.1415926
self.NUMIND = 25
self.FUN = 1
self.crossPro = 0.9
self.mutaPro = 0.1
self.pop = self.popu()
class indivi:
def __init__(self):
self.geneX1 = 0.0
self.geneX2 = 0.0
self.fitness = 0.0
class popu:
def __init__(self):
self.indv = [GeneticAlgorithm.indivi() for n in range(GeneticAlgorithm.NUMIND)]
self.bestInd = GeneticAlgorithm.indivi()
self.generan = 0
def ranF(self, x, y):
return random.uniform(x, y)
def fit(self, x1, x2, i):
if i == 1:
return 3*(x1**2 - x2)**2
else:
return x1,x2
def dou2ZD(self, x, lowBef, upBef, lowAft, upAft):
return lowAft + (x - lowBef) * (upAft - lowAft) / (upBef - lowBef)
def initPop(self):
self.pop.generan = 0
for indv in self.pop.indv:
indv.geneX1 = self.ranF(0, 1024)
indv.geneX2 = self.ranF(0, 1024)
def calFit(self):
for indv in self.pop.indv:
indv.geneX1 = self.dou2ZD(indv.geneX1, 0, 1024, -10, 10)
indv.geneX2 = self.dou2ZD(indv.geneX2, 0, 1024, -10, 10)
indv.fitness = self.fit(indv.geneX1, indv.geneX2, self.FUN)
def calUp(self):
sum = 0.0
for indv in self.pop.indv:
sum += indv.fitness
self.pop.indv[0].upLim = self.pop.indv[0].fitness / sum
for i in range(self.NUMIND-1):
temp = self.pop.indv[i+1].fitness / sum
self.pop.indv[i+1].upLim = temp + self.pop.indv[i].upLim
if self.pop.indv[i+1].upLim > 1.0 and (i+1) < (self.NUMIND-1):
for j in range(self.NUMIND):
print('generation is:{},fitness={},UpLim={}'.format(self.pop.generan,self.pop.indv[j].fitness,self.pop.indv[j].upLim))
print('
Error,{}'s upLim is greater than 1=============
'.format(i+1))
exit(0)
self.pop.indv[self.NUMIND-1].upLim = 1
def HalfSear(self, value, LowBo, UpBo, InA):
if LowBo >= UpBo:
return UpBo
Mid = (LowBo + UpBo) // 2
if Mid == 0:
return 0
if value <= InA[Mid] and value > InA[Mid-1]:
return Mid
else:
if value >= InA[Mid]:
return self.HalfSear(value, Mid, UpBo, InA)
else:
return self.HalfSear(value, LowBo, Mid, InA)
def calSub(self):
poptem = self.popu()
TemFitn = [indv.upLim for indv in self.pop.indv]
for i in range(self.NUMIND):
rnd = self.ranF(0, 1)
NumTemp = self.HalfSear(rnd, 0, self.NUMIND, TemFitn)
poptem.indv[i] = self.pop.indv[NumTemp]
poptem.generan = self.pop.generan
poptem.bestInd = self.pop.bestInd
self.pop = poptem
def select(self):
self.calUp()
self.calSub()
def crossove(self):
for i in range(self.NUMIND//2):
if random.random() > self.crossPro:
continue
else:
j = random.randint(0, self.NUMIND-1)
k = random.randint(0, self.NUMIND-1)
a = self.ranF(0, 1)
self.pop.indv[j].geneX1 = a * self.pop.indv[j].geneX1 + (1 - a) * self.pop.indv[k].geneX1
self.pop.indv[j].geneX2 = a * self.pop.indv[j].geneX2 + (1 - a) * self.pop.indv[k].geneX2
self.pop.indv[k].geneX1 = a * self.pop.indv[k].geneX1 + (1 - a) * self.pop.indv[j].geneX1
self.pop.indv[k].geneX2 = a * self.pop.indv[k].geneX2 + (1 - a) * self.pop.indv[j].geneX2
def mutation(self):
for i in range(self.NUMIND):
if random.random() > self.mutaPro:
continue
else:
self.pop.indv[i].geneX1 = self.ranF(0, 1024)
self.pop.indv[i].geneX2 = self.ranF(0, 1024)
def max(self):
j = 0
tem = self.pop.indv[0].fitness
for i in range(1, self.NUMIND):
if self.pop.indv[i].fitness > tem:
tem = self.pop.indv[i].fitness
j = i
self.pop.bestInd = copy.deepcopy(self.pop.indv[j])
def run(self):
random.seed(time.time() % 9)
self.initPop()
fp = open('a.txt', 'w')
if not fp:
print('Can't open file')
exit(0)
while self.pop.bestInd.fitness <= 40000 and self.pop.generan < 10000:
self.calFit()
self.max()
print('The generation is {}, the best fitness is {}'.format(self.pop.generan, self.pop.bestInd.fitness))
fp.write('Best Individual: X1={}, X2={}, {}
'.format(self.pop.bestInd.geneX1, self.pop.bestInd.geneX2, self.pop.bestInd.fitness))
self.select()
self.crossove()
if self.pop.generan == 100:
self.mutaPro = 0.3
print('The mutation probability is set to 0.3')
self.mutation()
self.pop.indv[0] = self.pop.bestInd
self.pop.generan +=1
print('finished')
fp.close()
# 使用示例
# 创建工厂对象
ga = GeneticAlgorithm()
# 运行遗传算法
ga.run()
代码说明:
- 工厂类
GeneticAlgorithm: 该类负责创建遗传算法对象,并提供一些通用的方法,例如初始化种群、计算适应度、选择、交叉和变异等。 - 内部类
indivi: 表示一个染色体,包含基因和适应度值。 - 内部类
popu: 表示一个种群,包含所有染色体和最佳染色体等信息。 run方法: 执行遗传算法,并输出结果。
工厂模式的好处:
- 代码可重用: 可以重复使用该工厂类创建不同的遗传算法对象,只需要修改参数即可。
- 代码可维护: 将代码封装在一个工厂类中,更容易维护和修改。
优化点:
- 使用了
random.seed方法来设置随机数种子,保证每次运行代码时都能获得相同的随机数序列,方便调试。 - 使用了
open方法打开文件,并使用fp.write方法写入数据,方便保存算法运行过程中的结果。 - 将代码中的一些关键变量设置为类属性,方便访问和修改。
- 使用了
copy.deepcopy方法来复制最佳染色体,避免修改原染色体。
总结:
本文介绍了如何使用工厂模式封装Python遗传算法。通过工厂模式,可以有效提高代码的可重用性和可维护性。同时,本文还对代码进行了SEO优化,方便搜索引擎收录。
希望本文对您有所帮助。如果您有任何问题或建议,请随时提出。
注意: 本文提供的代码仅供参考,您可以根据自己的需求进行修改和完善。
原文地址: https://www.cveoy.top/t/topic/nyy8 著作权归作者所有。请勿转载和采集!