如何保持可变长度

时间:2016-11-07 13:05:01

标签: python algorithm genetic deap

我对在Python中使用DEAP的遗传算法感兴趣。 knapasack can be seen here的示例实现。我试图创建自己的交叉功能,我想保留父母的长度,如下所示:

# Crossover
def crossover(ind1, ind2):
    print len(ind1), len(ind2) #<------ length at the beginning
    temp1 = copy.deepcopy(set(ind1))
    temp2 = copy.deepcopy(set(ind2))
    uniform = list(temp1.union(temp2))
    while len(ind1) > 0:
        ind1.pop()
    while len(ind2) > 0:
        ind2.pop()
    for i in range(max_no):
        ind1.add(random.choice(uniform))
        ind2.add(random.choice(uniform))
    print len(ind1), len(ind2) #<---- length at the end
    return ind1, ind2

但是,函数开头的ind1和in2的长度与最后的ind1和ind2的长度不同。开头的ind1和ind2的长度应该等于max_no。我希望有人能给我一个暗示,为什么会这样。我很难过。

谢谢,任何帮助将不胜感激。

编辑:这是我的变异功能。我还试图在这里保留可变长度的个体

def mutation(individual):
    if len(individual) > 0:
        individual.remove(random.choice(list(individual)))
        individual.add(random.choice(nodes))
    return individual,

1 个答案:

答案 0 :(得分:1)

您的代码大致相当于:

import random

ind1 = set(range(100))
ind2 = set(range(100)[::-1])
uniform = list(ind1.union(ind2))
max_no = 100
while len(ind1) > 0:
        ind1.pop()
while len(ind2) > 0:
    ind2.pop()
for i in range(max_no):
    ind1.add(random.choice(uniform))
    ind2.add(random.choice(uniform))

结果

>>> print(len(ind1),len(ind2))
(64, 61)

因为您的个人是集合,所以当您添加随机数时,每隔一段时间就会添加一些东西。然后,结果集的长度在每次运行时都会有所不同,因为如果它已经存在于个体中,则不会添加任何内容。

要解决您的问题,您可以改为使用random.sample

import random

ind1 = set(range(100))
ind2 = set(range(-100,0,-1)[::-1])
uniform = list(ind1.union(ind2))
max_no = 100
while len(ind1) > 0:
    ind1.pop()
while len(ind2) > 0:
    ind2.pop()
for x in random.sample(uniform,max_no):
    ind1.add(x)
for x in random.sample(uniform,max_no):
    ind2.add(x)

结果

>>> print(len(ind1),len(ind2))
(100, 100)

话虽如此,set个人对我来说非常痛苦。到目前为止,sequence个人是最好的支持者。从documentation来看dictset dict float[] pathArray = new float[(nodes.size() - 1) * 4]; for (int i = 0; i < nodes.size() - 1; i++) { int index = i * 4; Node from = nodes.get(i); pathArray[index] = from.x; pathArray[index + 1] = from.y; Node to = nodes.get(i + 1); pathArray[index + 2] = to.x; pathArray[index + 3] = to.y; } 的特殊情况not considered sequence types:

  

序列

     

一个iterable,支持使用整数进行有效的元素访问   索引通过 getitem ()特殊方法定义 len ()   返回序列长度的方法。一些内置的序列   类型是list,str,tuple和bytes。请注意,dict也支持    getitem ()和 len (),但被认为是映射而不是序列,因为查找使用任意不可变键而不是   整数。