遺伝的アルゴリズムで遊ぶ 2
突然変異つけないと話にならないので、つけました。ようやくスタートライン一歩手前ですかね
# coding: utf-8 import random import copy generation = [] population_size = 10 chrom_size = 10 mutation_rate = 1 def initialize(): global population_size global generation for i in range(population_size): chrom = [] for j in range(chrom_size): chrom.append(random.randint(0,1)) generation.append(chrom) def fitness(indiv): global population_size count = 0.0 for x in indiv: if x==1: count+=1 if count <= 5: return 0.5 return count/population_size # 一点交叉 def crossover(p1, p2): if len(p1)>len(p2): maximum = len(p2)-1 else: maximum = len(p1) - 1 point = random.randint(0,maximum) for i in range(point,maximum+1): x = p1[i] p1[i] = p2[i] p2[i] = x return p1, p2 # バブルソート def calculate_fit(): global generation k = len(generation) - 1 for i in range(k): for j in xrange(k,i,-1): if fitness(generation[j-1])>fitness(generation[j]): t = generation[j-1] generation[j-1] = generation[j] generation[j] = t def simple_crossover(): global generation max = len(generation)-1 select1 = random.randint(0,max) select2 = random.randint(0,max) while select1==select2: select2 = random.randint(0,max) p1 = generation[select1] p2 = generation[select2] p1,p2 = crossover(p1,p2) # fitnessの高い方を返す if fitness(p1)>fitness(p2): return p1 return p2 def fitness_average(): global generation global population_size total = 0.0 for x in generation: total += fitness(x) return total / population_size def dump_chrom(gene_count): global generation print "%d世代" % gene_count for x in generation: for y in x: print y, print print "\n" def mutation(p1,rate, num): if num > len(p1):num=len(p1) if (rate>1) or (rate<0): return if random.randint(0,100)/100.0 <= rate: for i in range(num): point = random.randint(0,len(p1)-1) p1[point] = random.randint(0,1) return p1 def simple_mutation(): return mutation(copy.deepcopy(generation[population_size-1]), 0.91, 5) def main(): global generation global population_size global mutation_rate initialize() calculate_fit() for i in range(population_size): next_generation = [] next_generation.append(copy.deepcopy(generation[population_size-1])) for j in range(population_size-1-mutation_rate): next_generation.append(simple_crossover()) for k in range(j+1, population_size-1): next_generation.append(simple_mutation()) generation = copy.deepcopy(next_generation) calculate_fit() for x in generation[population_size-1]: print x, print fitness_average() #dump_chrom(i) if __name__ == '__main__': main()
まぁこの程度だと、あんまり違いが分かりませんが。
0 1 1 1 0 1 1 1 0 1 0.57 0 1 1 0 1 1 0 1 1 1 0.6 0 1 1 1 1 1 1 0 0 1 0.61 0 1 1 1 1 1 1 1 1 1 0.77 0 1 1 1 1 1 1 1 1 1 0.79 1 1 1 1 0 1 1 1 1 1 0.79 0 1 1 1 1 1 1 1 1 1 0.81 1 1 1 1 1 1 1 1 1 1 0.8 1 1 1 1 1 1 1 1 1 1 0.88 1 1 1 1 1 1 1 1 1 1 0.93
一番右の値は全体の個体の適応度の平均値です。