我有具有属性健身对象(染色体)(chromosome.fitness是0和1之间)的列表
鉴于这种对象的列表,我怎么能实现它返回它的机会被选中的正比于它的健身一条染色体的功能? 也就是说,健身0.8染色体是两倍,可能被选择为一个有健身0.4。
我已经发现了一些Python和伪代码实现,但它们对于这个要求太复杂:该功能只需要一个染色体的列表。 染色体存储他们自己的健康,内部变量。
我已经写的实施是在我决定让染色体来存储自己的健身,所以是一个复杂得多,涉及荏苒列表和东西。
- - - - - - - - - - - - - - 编辑 - - - - - - - - - - - -------
谢谢Lattyware。 下面的函数似乎工作。
def selectOne(self, population):
max = sum([c.fitness for c in population])
pick = random.uniform(0, max)
current = 0
for chromosome in population:
current += chromosome.fitness
if current > pick:
return chromosome
有一个很简单的方法来选择字典的加权随机选择:
def weighted_random_choice(choices):
max = sum(choices.values())
pick = random.uniform(0, max)
current = 0
for key, value in choices.items():
current += value
if current > pick:
return key
如果手边有一本字典,你不这样做,你可以对此进行修改你的类(因为你没有给它的更多详细信息,或生成词典:
choices = {chromosome: chromosome.fitness for chromosome in chromosomes}
假定该健身是一个属性。
下面是修改,以染色体的一个可迭代,再次,使得相同的推定功能的一个例子。
def weighted_random_choice(chromosomes):
max = sum(chromosome.fitness for chromosome in chromosomes)
pick = random.uniform(0, max)
current = 0
for chromosome in chromosomes:
current += chromosome.fitness
if current > pick:
return chromosome
使用numpy.random.choice。
import numpy.random as npr
def selectOne(self, population):
max = sum([c.fitness for c in population])
selection_probs = [c.fitness/max for c in population]
return population[npr.choice(len(population), p=selection_probs)]
from __future__ import division
import numpy as np
import random,pdb
import operator
def roulette_selection(weights):
'''performs weighted selection or roulette wheel selection on a list
and returns the index selected from the list'''
# sort the weights in ascending order
sorted_indexed_weights = sorted(enumerate(weights), key=operator.itemgetter(1));
indices, sorted_weights = zip(*sorted_indexed_weights);
# calculate the cumulative probability
tot_sum=sum(sorted_weights)
prob = [x/tot_sum for x in sorted_weights]
cum_prob=np.cumsum(prob)
# select a random a number in the range [0,1]
random_num=random.random()
for index_value, cum_prob_value in zip(indices,cum_prob):
if random_num < cum_prob_value:
return index_value
if __name__ == "__main__":
weights=[1,2,6,4,3,7,20]
print (roulette_selection(weights))
weights=[1,2,2,2,2,2,2]
print (roulette_selection(weights))
我宁愿少行:
import itertools
def choose(population):
bounds = list(itertools.accumulate(chromosome.fitness for chromosome in population))
pick = random.random() * bounds[-1]
return next(chromosome for chromosome, bound in zip(population, bounds) if pick < bound)
import random
def weighted_choice(items):
total_weight = sum(item.weight for item in items)
weight_to_target = random.uniform(0, total_weight)
for item in items:
weight_to_target -= item.weight
if weight_to_target <= 0:
return item