2015-06-23 143 views
0

演變函數與變種函數一樣存在問題。Python遺傳算法

from random import randint, random 
    from operator import add 
    from functools import reduce 



    def individual(length, min, max): 
     'Create a member of the population.' 
     return [randint(min,max) for x in range(length)] 


    def population(count, length, min, max): 
     'Create a number of individuals (i.e. a population).' 
     return [ individual(length, min, max) for x in range(count) ] 


    def fitness(individual, target): 
     'Determine the fitness of an individual. Lower is better.' 
     sum = reduce(add, individual, 0) 
     return abs(target-sum) 


    def grade(pop, target): 
     'Find average fitness for a population.' 
     summed = reduce(add, (fitness(x, target) for x in pop), 0) 
     return summed/(len(pop) * 1.0) 


    chance_to_mutate = 0.01 
    for i in p: 
     if chance_to_mutate > random(): 
      place_to_modify = randint(0,len(i)) 
      i[place_to_modify] = randint(min(i), max(i)) 


    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] 

     # randomly add other individuals to promote genetic diversity 
     for individual in graded[retain_length:]: 
      if random_select > random(): 
       parents.append(individual) 

     # mutate some individuals 
     for individual in parents: 
      if mutate > random(): 
       pos_to_mutate = randint(0, len(individual)-1) 
       # this mutation is not ideal, because it 
       # restricts the range of possible values, 
       # but the function is unaware of the min/max 
       # values used to create the individuals, 
       individual[pos_to_mutate] = randint(
        min(individual), max(individual)) 

     # crossover parents to create children 
     parents_length = len(parents) 
     desired_length = len(pop) - parents_length 
     children = [] 
     while len(children) < desired_length: 
      male = randint(0, parents_length-1) 
      female = 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 = 5 
    i_min = 0 
    i_max = 100 
    p = population(p_count, i_length, i_min, i_max) 
    fitness_history = [grade(p, target),] 
    for i in range(100): 
     p = evolve(p, target) 
     fitness_history.append(grade(p, target)) 

    for datum in fitness_history: 
     print(datum) 

我下面這個網站http://lethain.com/genetic-algorithms-cool-name-damn-simple/。它是爲Python 2.6編寫的,因此它不適用於3.我已經對它進行了更新,但無法使其工作。

+0

你被關閉,投票;請參閱http://stackoverflow.com/help/how-to-ask並在您的問題中添加足夠的細節,以便人們可以提供幫助,例如對此無能爲力 - 它應該做什麼,與實際做的相比,以及我們如何測試它。 – TessellatingHeckler

+0

沒有'mutate'功能。 –

+0

如果下次你輸入'[ask]'而不是'stackoverflow.com/help/how-to-ask',你可能希望自己保存一些輸入@TessellatingHeckler。 – boardrider

回答

1

代碼引起的錯誤應該足夠豐富。切片完成:

male[:half] + female[half:] 

正在使用一半,這是當時的浮動。主要區別是:

half = int(len(male)/2) 

這可能是預期的功能。你不能使用浮點數來索引一個數組,只有整數。

這是它應該是什麼:

from random import randint, random 
from functools import reduce 
from operator import add 
def individual(length, min, max): 
    'Create a member of the population.' 
    return [randint(min,max) for x in range(length)] 


def population(count, length, min, max): 
    'Create a number of individuals (i.e. a population).' 
    return [ individual(length, min, max) for x in range(count) ] 


def fitness(individual, target): 
    'Determine the fitness of an individual. Lower is better.' 
    sum = reduce(add, individual, 0) 
    return abs(target-sum) 


def grade(pop, target): 
    'Find average fitness for a population.' 
    summed = reduce(add, (fitness(x, target) for x in pop), 0) 
    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] 

# randomly add other individuals to promote genetic diversity 
for individual in graded[retain_length:]: 
    if random_select > random(): 
     parents.append(individual) 

# mutate some individuals 
for individual in parents: 
    if mutate > random(): 
     pos_to_mutate = randint(0, len(individual)-1) 
     # this mutation is not ideal, because it 
     # restricts the range of possible values, 
     # but the function is unaware of the min/max 
     # values used to create the individuals, 
     individual[pos_to_mutate] = randint(
      min(individual), max(individual)) 

# crossover parents to create children 
parents_length = len(parents) 
desired_length = len(pop) - parents_length 
children = [] 
while len(children) < desired_length: 
    male = randint(0, parents_length-1) 
    female = randint(0, parents_length-1) 
    if male != female: 
     male = parents[male] 
     female = parents[female] 
     half = int(len(male)/2) 
     child = male[:half] + female[half:] 
     children.append(child) 

parents.extend(children) 
return parents 

target = 371 
p_count = 100 
i_length = 5 
i_min = 0 
i_max = 100 
p = population(p_count, i_length, i_min, i_max) 
fitness_history = [grade(p, target),] 
chance_to_mutate = 0.01 
for i in p: 
    if chance_to_mutate > random(): 
     place_to_modify = randint(0,len(i)) 
     i[place_to_modify] = randint(min(i), max(i)) 
for i in range(100): 
    p = evolve(p, target) 
    fitness_history.append(grade(p, target)) 

for datum in fitness_history: 
    print(datum)