-1
population=[[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [0]],
[[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]],
[[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]],
[[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [1], [3]]]    

selected_chromosomes=[[[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]]]

child1=[0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]
child2=[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1]   



def PopulationAdjustment(population, selected_chromosomes):
    for game in range(0, len(selected_chromosomes)):
        if game in selected_chromosomes[game][2]==game in population[game][2]: 
            population.remove(game)
    return population  

所以这里的目标是替换人口(列表)中的孩子的父母,我的方法是删除父母然后附加孩子,基于相同的计数器。列表的结构是[[chromosome],[fitness],[counter]],但是它们并不完全相同,因为我在选择过程中操纵了适应度以避免 0 概率。

我正在尝试索引具有相同计数器的项目并将它们从列表中删除,然后下一步将只针对append孩子。

我一直在尝试一些不同的方法,但我无法让它正常工作,关于如何解决这个问题的任何想法?此外,如果有一种方法可以直接由孩子们替换它们而无需执行 2 个步骤(删除和附加),那也将非常受欢迎。谢谢!!

4

1 回答 1

1

您说“我正在尝试索引具有相同计数器的项目并将它们从列表中删除”。虽然这是可能的,但构建一个包含您想要保留的染色体的新列表更容易(也更快),除非population它很大。

我们首先扫描selected_chromosomes它们以将它们的计数器编号提取到一个集合中,以便我们可以快速查找它们。

population=[
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [0]],
    [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]],
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]],
    [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [1], [3]],
]

selected_chromosomes=[
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]],
]

def population_adjustment(population, selected_chromosomes):
    # Create a set of the counter numbers to remove
    drop = {u[-1][0] for u in selected_chromosomes}

    # Copy the wanted chromosomes to a new list
    return [u for u in population if u[-1][0] not in drop]

new_pop = population_adjustment(population, selected_chromosomes)
for row in new_pop:
    print(row)

输出

[[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]]
[[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [1], [3]]

如果population列表很大,或者您有其他原因保留原始列表(例如,在不同的地方有多个引用它),这里是删除不需要的列表的方法。不过,我们必须小心。从您正在迭代的列表中删除项目是危险的,因为删除会干扰剩余列表项的索引,如此处所示。这有点像砍掉你正坐在上面的树枝。如果你切错了地方,坏事就会发生。;) 最简单的方法是反向迭代列表。

population=[
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [4], [0]],
    [[0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], [3], [1]],
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [4], [2]],
    [[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0], [1], [3]],
]

selected_chromosomes=[
    [[0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0], [5], [2]],
    [[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], [3], [0]],
]

def population_adjustment(population, selected_chromosomes):
    # Create a set of the counter numbers to remove
    drop = {u[-1][0] for u in selected_chromosomes}

    # Iterate backwards over population so we can safely delete sublists
    for i in range(len(population)-1, -1, -1):
        k = population[i][-1][0]
        if k in drop:
           del population[i] 

    # Since we mutate `population` we should return `None`, as is conventional in Python.
    # This return statement isn't necessary, since `None` is the default return value,
    # but it's nice to be explicit
    return None

population_adjustment(population, selected_chromosomes)
for row in population:
    print(row)

这段代码产生的输出与以前的版本相同,所以我不会重复它。

于 2017-11-17T14:03:50.617 回答