Pythonで遺伝的アルゴリズムのフレームワークを作成しようとしていますが、浅い/深いコピーで問題が発生しています。私のバックグラウンドは主にC/C ++であり、これらの接続がどのように持続しているかを理解するのに苦労しています。
私が見ているのは、サブクラス内の属性リストの長さが爆発的に増加していることです。私のコードは以下のとおりです...問題を指摘します。
これは単一の遺伝子のクラスです。基本的に、名前、値、およびブールフラグが必要です。私のクラスGene
内のリストにデータを入力するインスタンス。Individual
# gene class
class Gene():
# constructor
def __init__(self, name, is_float):
self.name_ = name
self.is_float_ = is_float
self.value_ = self.randomize_gene()
# create a random gene
def randomize_gene(self):
return random.random()
これは私のIndividual
クラスです。世代ごとに、これらの母集団が作成され(クラス宣言の後に作成コードを示します)、一般的な遺伝的アルゴリズム操作が適用されます。注目すべきは、print len(self.Genes_)
このクラスがインスタンス化されるたびに大きくなる呼び出しです。
# individual class
class Individual():
# genome definition
Genes_ = [] # genes list
evaluated_ = False # prevent re-evaluation
fitness_ = 0.0 # fitness value (from evaluation)
trace_ = "" # path to trace file
generation_ = 0 # generation to which this individual belonged
indiv_ = 0 # identify this individual by number
# constructor
def __init__(self, gen, indv):
# assign indices
self.generation_ = gen
self.indiv_ = indv
self.fitness_ = random.random()
# populate genome
for lp in cfg.params_:
g = Gene(lp[0], lp[1])
self.Genes_.append(g)
print len(self.Genes_)
> python ga.py
> 24
> 48
> 72
> 96
> 120
> 144
......
ご覧のとおり、各個体には24個の遺伝子が必要ですが、この集団は非常に急速に爆発します。私はこのような新しい個人の初期集団を作成します:
# create a randomized initial population
def createPopulation(self, gen):
loc_population = []
for i in range(0, cfg.population_size_):
indv = Individual(gen, i)
loc_population.append(indv)
return loc_population
その後、メインループで(ダンプ全体についてお詫びしますが、必要だと感じました。セカンダリ呼び出し(ミューテーション/クロスオーバー)が必要な場合はお知らせください))
for i in range(0, cfg.generations_):
# evaluate current population
self.evaluate(i)
# sort population on fitness
loc_pop = sorted(self.population_, key=operator.attrgetter('fitness_'), reverse=True)
# create next population & preserve elite individual
next_population = []
elitist = copy.deepcopy(loc_pop[0])
elitist.generation_ = i
next_population.append(elitist)
# perform selection
selection_pool = []
selection_pool = self.selection(elitist)
# perform crossover on selection
new_children = []
new_children = self.crossover(selection_pool, i)
# perform mutation on selection
muties = []
muties = self.mutation(selection_pool, i)
# add members to next population
next_population = next_population + new_children + muties
# fill out the rest with random
for j in xrange(len(next_population)-1, cfg.population_size_ - 1):
next_population.append(Individual(i, j))
# copy next population over old population
self.population_ = copy.deepcopy(next_population)
# clear old lists
selection_pool[:] = []
new_children[:] = []
muties[:] = []
next_population[:] = []