1

Pythonで書いた遺伝的アルゴリズムを実行しようとしています。残念なことに、突然変異があると、エリート主義を使用して前の世代から新しい世代に最適な解を渡すにもかかわらず、最適な解が前の世代の最適な解よりも悪くなる可能性があります。そのようです:

There are 86825 generations left
Invalid count is:  0
The fittest individual has a fitness of 16.9094. 
The least fit individual has a fitness  of 36.6535
*******************************************************************************
mutation on 107
There are 86824 generations left
Invalid count is:  3
The fittest individual has a fitness of 19.8637. 
The least fit individual has a fitness of 1.1618e+09

私は、これを回避できると考えたエリート主義を実装しようとしましたが、それでも発生します。私のアルゴリズムは次の順序で実行されます。

NUM_GEN = 100000
print "Running Genetic Algorithm for %d generations." % NUM_GEN
gen_count = 0
while gen_count < NUM_GEN:
    #genetic.add_fitness_key()
    genetic.add_fitness_fast()
    fittest_list = np.append(fittest_list, genetic.fittest_fitness)
    least_fit_list = np.append(least_fit_list, genetic.least_fitness)
    genetic.sort_pop()
    genetic.make_new_pop()
    genetic.elitism()
    genetic.population = genetic.new_pop
    print "There are %g generations left" %(NUM_GEN-gen_count) 
    gen_count+=1

そして、呼び出される関数は次のとおりです。

def select_parent_from_tournament(self):
    x = random.randint(0, 19)
    player1 = self.population[x]
    y = random.randint(0, 19)
    player2 = self.population[y]
    if player1['fitness'] <= player2['fitness']:
        parent = player1['chrom_list']
    else:
        parent = player2['chrom_list']
    return parent

def crossover(self):
    crossover_point = random.randint(0, self.chromosome_size)*(self.string_length)
    parent1 = self.select_parent_from_tournament()
    parent2 = self.select_parent_from_tournament()
    parent1 = self.mutate(parent1)
    parent2 = self.mutate(parent2)
    child1 = parent1[:crossover_point] + parent2[crossover_point:]
    child2 = parent1[crossover_point:] + parent2[:crossover_point]
    return child1, child2

def mutate(self, chromosome):
    for i in range(len(chromosome)):
        if random.random() < self.mutation_rate:
            print 'mutation on %i' % i
            if chromosome[i] =='0':
                chromosome[i] = '1'
            else:
                chromosome[i] = '0'
    return chromosome

def make_new_pop(self):
    self.new_pop = []
    for i in range(10):
        dictionary1= {}
        dictionary2 = {}
        dictionary1['chrom_list'], dictionary2['chrom_list'] = \
        self.crossover()
        self.new_pop = np.append(self.new_pop, [dictionary1, dictionary2])

def elitism(self):
    r = random.randint(0, 19)
    self.new_pop[r] = self.population[0]

突然変異がある場合、なぜ古い母集団からの最適解が新しい母集団に渡されないのか理解できませんか?

4

1 に答える 1

4

parent1 = self.select_parent_from_tournament()クロスオーバー メソッドでは、元の母集団から染色体のリストへの参照を返すを実行します。その後、(元の母集団の) リストを変更する突然変異を行います。変異後にのみ、 を介して子のコンテンツをコピーしますchild1 = parent1[:crossover_point] + parent2[crossover_point:]。@Xavier が示唆していたように、元の母集団から要素の物理コピーを作成する必要がありますmutation()

実際、あなたのmutation()方法は元の母集団を変更しました。

補足として、一般にクロスオーバーとミューテーションは 2 つの異なる操作です。また、文献には、突然変異の確率を非常に低く抑える必要があることを示唆する参考文献があります。そうしないと、収束できなくなります。

于 2013-01-14T16:57:06.310 に答える