Python - 创建一个具有 2 个特征错误的列表



目标是创建一个包含 99 个元素的列表。所有元素都必须为 1 或 0。第一个元素必须是 1。总共必须有 7 个 1。

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, 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, 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, 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, 0, 1, 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] 2 假

我到底做错了什么?

我不确定我是否理解您的要求,但听起来您需要的是:

#!/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))

你给出的算法可以工作,尽管它很慢。请注意,理想generation_constant实际上可以使用二项分布来计算。最佳值为 ≈0.928571429,在 1.104% 的时间内适合条件。如果手动将第一个元素设置为 1,则最佳generation_constant为 ≈0.93877551,这将在 16.58% 的时间内满足条件。

以上基于二项分布,它表示在每次尝试概率为 pN 次总尝试中正好有 k 个"成功"事件的概率为 Pk | Np ) = 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,因为只有在 vector[0] == 1 时才调用index = random.randint(0, 98)

通过遗传编程,您希望控制您的域,以便尽可能消除无效配置。 适用性假定用于对有效配置进行评级,而不是消除无效配置。 老实说,这个问题似乎并不适合基因编程。 您已经概述了域。但我在任何地方都没有看到健身描述。

无论如何,话虽如此,我填充域的方式是:由于第一个元素始终是 1,请忽略它,因为其余 98 个元素只有 6 个 1,将 6 个 1 洗牌为 92 个零。甚至列举可能性,因为您的域不是很大。

我有一种感觉,这是你对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()
>>> 

最新更新