Python中的健身比例选择(轮盘赌选择)

Ror*_*ory 12 python random genetic-algorithm

我有一个对象列表(染色体),它具有属性适应性(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
Run Code Online (Sandbox Code Playgroud)

Gar*_*tty 10

有一种从字典中选择加权随机选择的简单方法:

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
Run Code Online (Sandbox Code Playgroud)

如果您手边没有字典,可以修改它以适合您的课程(因为您没有提供更多详细信息,或者生成字典:

choices = {chromosome: chromosome.fitness for chromosome in chromosomes}
Run Code Online (Sandbox Code Playgroud)

假设健身是一种属性.

以下是修改为采用可迭代染色体的函数的示例,再次进行相同的假设.

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
Run Code Online (Sandbox Code Playgroud)

  • 如果你有很多选择,或者你必须选择具有相同权重集的许多值,你也可以使用二进制搜索,甚至是O,将这个O(n)解决方案变成O(log(n))解决方案. (1)使用某种查找表的解决方案. (2认同)

cw'*_*cw' 8

使用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)]
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案:简单,而且可能比其他所有选项都更快 (3认同)