Dưới đây là một ví dụ tầm thường , trong đó nắm bắt bản chất của các thuật toán di truyền có ý nghĩa hơn so với đa thức bạn cung cấp. Đa thức bạn cung cấp có thể giải được thông qua stochastic gradient descent
, đây là một kỹ thuật tối thiểu hóa đơn giản hơn. Vì lý do này, tôi thay vào đó đề xuất bài viết và ví dụ tuyệt vời này của Will Larson.
Trích dẫn từ bài viết gốc :
Xác định một vấn đề để tối ưu hóa Bây giờ chúng ta sẽ đưa ra một ví dụ đơn giản về việc sử dụng thuật toán di truyền trong Python. Chúng ta sẽ tối ưu hóa một vấn đề rất đơn giản: cố gắng tạo một danh sách N số bằng X khi tổng hợp lại với nhau.
Nếu chúng ta đặt N = 5 và X = 200, thì đây sẽ là những giải pháp phù hợp.
lst = [40,40,40,40,40]
lst = [50,50,50,25,25]
lst = [200,0,0,0,0]
Hãy xem toàn bộ bài viết , nhưng đây là đoạn mã hoàn chỉnh :
# Example usage
from genetic import *
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(100):
p = evolve(p, target)
fitness_history.append(grade(p, target))
for datum in fitness_history:
print datum
"""
from random import randint, random
from operator import add
def individual(length, min, max):
'Create a member of the population.'
return [ randint(min,max) for x in xrange(length) ]
def population(count, length, min, max):
"""
Create a number of individuals (i.e. a population).
count: the number of individuals in the population
length: the number of values per individual
min: the minimum possible value in an individual's list of values
max: the maximum possible value in an individual's list of values
"""
return [ individual(length, min, max) for x in xrange(count) ]
def fitness(individual, target):
"""
Determine the fitness of an individual. Higher is better.
individual: the individual to evaluate
target: the target number individuals are aiming for
"""
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))
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 = len(male) / 2
child = male[:half] + female[half:]
children.append(child)
parents.extend(children)
return parents
Tôi nghĩ rằng nó có thể khá hữu ích về mặt sư phạm để giải quyết vấn đề ban đầu của bạn bằng thuật toán này và sau đó cũng xây dựng một giải pháp bằng cách sử dụng stochastic grid search
hoặc stochastic gradient descent
bạn sẽ hiểu sâu hơn về vị trí kề nhau của ba thuật toán đó.
Hi vọng điêu nay co ich!