您的位置:首页 > 其它

遗传算法示例

2014-04-12 23:04 281 查看
今晚简单研究下遗传算法,学习的是一个求N个数,使之加起来恰好为X的例子,比较简明易懂,python实现起来也很方便。

几个基础的概念:

个体individual,它有自己的生存力,也就是适应力,强弱就是与我们的目标的差距

种群population,个体的集合,生存力不同,有强有弱

适应力fitness,针对个体而言,越小越好,看它与目标的差距

评分grade,针对种群而言,同样越小越好,定义了所有个体与目标差距的平均值

进化evolve,核心部分,生物的物竞天择适者生存过程,不断淘汰种群中的弱者,留下强者,并从强者中选择2个作为父母繁衍后代,后代有父母的基因,同时产生的过程中有概率发生变异,也可以选择让父母产生变异,从结果上看效果是一样的。

下面的例子中,设定目标值371,种群中个体数100,每个个体由6个数组成,在0到100之间,每次进化留下的优良个体比例20%,不良个体被留下的概率为5%(这个可以不要,留下会表现有遗传的多样性),留下的个体中,变异概率1%。进化前会对种群中个体的适应力排序,选择一定比例的留下,然后让其中的每个按概率发生变异,结果作为父母,繁衍后代,直到个体总量达到规定值。这里,我们预先知道我们的目标值,因此发现有个体完全适应时就可以停止进化了,而有些问题并不能准确知道这个值,因此可以将结果不断的保留,最后取一个最值作为我们的结果,得到原问题的近似最优解。

# -*- coding:gbk -*-
import random, operator

def individual(length, min, max):
return [random.randint(min, max) for x in xrange(length)]

def population(count, length, min, max):
return [individual(length, min, max) for x in xrange(count)]

def fitness(individual, target):
sum = reduce(operator.add, individual, 0)
return abs(target - sum)

def grade(pop, target):
summed = reduce(operator.add, (fitness(x, target) for x in pop))
return summed / (len(pop) * 1.0)

def evolve(pop, target, retain = 0.2, random_select = 0.05, mutate = 0.01):
graded = [(fitness(x, target), x) for x in pop]
graded = [x[1] for x in sorted(graded)]
retain_length = int(len(graded) * retain)
parents = graded[:retain_length]
for individual in graded[retain_length:]:
if random_select > random.random():
parents.append(individual)

for individual in parents:
if mutate > random.random():
pos_to_mutate = random.randint(0, len(individual) - 1)
individual[pos_to_mutate] = random.randint(min(individual), max(individual))
parents_length = len(parents)
desired_length = len(pop) - parents_length
children = []
while len(children) < desired_length:
male = random.randint(0, parents_length - 1)
female = random.randint(0, parents_length - 1)
if male != female:
male = parents[male]
female = parents[female]
half = len(male) / 2
child = male[:half] + female[half:]
children.append(child)
parents.extend(children)
return parents

target = 371
p_count = 100
i_length = 6
i_min = 0
i_max = 100

p = population(p_count, i_length, i_min, i_max)
fitness_history = [grade(p, target),]
for i in xrange(200):
p = evolve(p, target)
g = grade(p, target)
fitness_history.append(g)
if g == 0:
break

for datum in fitness_history:
print datum

individual = p[len(p) - 1]
print 'individual is'
sum  = 0
for n in individual:
sum += n
print n
print 'total=%d,target=%d,evolve=%d'%(len(fitness_history), target, sum)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: