目标是创建99个元素的列表。所有元素必须为1或0。第一个元素必须是1.总共必须有7个。
import random
import math
import time
# constants determined through testing
generation_constant = 0.96
def generate_candidate():
coin_vector = []
coin_vector.append(1)
for i in range(0, 99):
random_value = random.random()
if (random_value > generation_constant):
coin_vector.append(1)
else:
coin_vector.append(0)
return coin_vector
def validate_candidate(vector):
vector_sum = sum(vector)
sum_test = False
if (vector_sum == 7):
sum_test = True
first_slot = vector[0]
first_test = False
if (first_slot == 1):
first_test = True
return (sum_test and first_test)
vector1 = generate_candidate()
while (validate_candidate(vector1) == False):
vector1 = generate_candidate()
print vector1, sum(vector1), validate_candidate(vector1)
大多数情况下,输出是正确的,如
[1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0] 7真
但有时输出为:
[0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 2错误
我究竟做错了什么?
答案 0 :(得分:1)
你给出的算法虽然很慢,却有效。请注意,理想generation_constant
实际上可以使用二项分布计算。最佳值为≈0.928571429,符合1.104%的时间条件。如果手动将第一个元素设置为1,那么最佳generation_constant
是≈0.93877551,这将适合16.58%的条件。
以上是基于二项分布,它表示准确 k "成功" N 总计中的事件,其中每次尝试的概率 p 将 P ( k | N , p )= N ! * p ^ k *(1 - p )^( N - k )/( n !*( N - k ))。只需将其粘贴到Excel,Mathematica或图形计算器中,并最大化 P 。
的可替换地:强> 的
要生成99个数字的列表,其中第一个和第6个附加项目为1,其余元素为0,您不需要这么多地调用random.random
。生成伪随机数非常昂贵。
有两种方法可以避免这么多地调用random
。
处理器效率最高的方法是只需要随机调用6次,对于需要插入的6个:
import random
# create vector of 99 0's
vector = [0 for i in range(99)]
# set first element to 1
vector[0] = 1
# list of locations of all 0's
indexes = range(1, 99)
# only need to loop 6 times for remaining 6 ones
for i in range(6):
# select one of the 0 locations at random
# "pop" it from the list so it can't be selected again
# and set it's coresponding element in vector to 1.
vector[indexes.pop(random.randint(0, len(indexes) - 1))] = 1
或者,为了节省内存,您可以只测试每个新索引以确保它实际设置一些内容:
import random
# create vector of 99 0's
vector = [0 for i in range(99)]
# only need to loop 7 times
for i in range(7):
index = 0 # first element is set to 1 first
while vector[index] == 1: # keep calling random until a 0 is found
index = random.randint(0, 98) # random index to check/set
vector[index] = 1 # set the random (or first) element to 1
第二个元素将始终将第一个元素设置为1,因为只有index = random.randint(0, 98)
才会调用vector[0] == 1
。
答案 1 :(得分:1)
我不确定我理解你的要求,但这听起来像是你需要的:
#!/usr/bin/python3
import random
ones = [ 1 for i in range(6) ]
zeros = [ 0 for i in range(99 - 6) ]
list_ = ones + zeros
random.shuffle(list_)
list_.insert(0, 1)
print(list_)
print(list_.count(1))
print(list_.count(0))
HTH
答案 2 :(得分:0)
使用遗传编程,您希望控制您的域,以便尽可能消除无效配置。适合度假设对有效配置进行评级,而不是消除无效配置。老实说,这个问题似乎并不适合遗传编程。您已概述了域名。但我在任何地方都没有看到健身描述。
无论如何,正如我所说,我填充域的方式是:因为第一个元素总是1,所以忽略它,因为剩下的98只有6个,随机抽取6个到92个零。或者甚至列举可能,因为您的域名不是很大。
答案 3 :(得分:0)
我感觉这是你使用sum()。我相信这会修改列表:
>>> mylist = [1,2,3,4]
>>> sum(mylist)
10
>>> mylist
[]
这是一个(有点)pythonic递归版本
def generate_vector():
generation_constant = .96
myvector = [1]+[ 1 if random.random() > generation_constant else 0 for i in range(0,99)]
mysum = 0
for a in myvector:
mysum = (mysum + a)
if mysum == 7 and myvector[0]==1:
return myvector
return generate_vector()
并采取良好措施
def generate_test():
for i in range(0,10000):
vector = generate_vector()
sum = 0
for a in vector:
sum = sum + a
if sum != 7 or vector[0]!=1:
print vector
输出:
>>> generate_test()
>>>