如何保留可变长度
How to preserve variable length
我有兴趣在 Python 中使用 DEAP 应用遗传算法。 knapasack can be seen here 的示例实现。我正在尝试创建自己的交叉函数,我想保留 parents 的长度,如下所示:
# 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,
您的代码大致等同于:
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 it's apparent that dict
and set
as a special case of dict
are not considered sequence
types:
sequence
An iterable which supports efficient element access using integer
indices via the getitem() special method and defines a len()
method that returns the length of the sequence. Some built-in sequence
types are list, str, tuple, and bytes. Note that dict also supports
getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than
integers.
我有兴趣在 Python 中使用 DEAP 应用遗传算法。 knapasack can be seen here 的示例实现。我正在尝试创建自己的交叉函数,我想保留 parents 的长度,如下所示:
# 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,
您的代码大致等同于:
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 it's apparent that dict
and set
as a special case of dict
are not considered sequence
types:
sequence
An iterable which supports efficient element access using integer indices via the getitem() special method and defines a len() method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports getitem() and len(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers.