使用python list在二进制变量上运行长度控制为2

时间:2018-09-21 18:08:30

标签: python python-2.7

我想伪随机地创建一个包含48个条目的列表-24个零和24个-其中零和一个都不连续重复两次以上。例如:

[1,1,0,1,0,0,1,1,0,1,0,...]

import random
l = list()
for i in range(48):
    if len(l) < 2:
        l.append(random.choice([0,1]))
    else:
        if l[i-1] == l[i-2]:
            if l[i-1] == 0:
                l.append(1)
            else:
                l.append(0)
        else:
            l.append(random.choice([0,1]))

我有上面的代码,但有时返回不均匀的1或0。所有可能的解决方案都应具有相同的出现机会。

2 个答案:

答案 0 :(得分:1)

这是一个接受整数n并返回包含n 0和n 1的列表的函数。

它首先通过随机选择整数0或1并尝试通过随机选择一个位置并将其插入列表中的某个位置并检查在该位置插入整数是否违反行为来遵守“连续3个约束”约束。如果没有,它将插入该位置,否则它将随机选择其他位置进行尝试。一直持续到所有n 0和所有n 1被放置在列表中

通过将每个0和1插入列表后递减一个计数器来跟踪到目前为止已使用的0和1。如果没有更多的0可添加,它将添加其余的1(反之亦然)。

一旦列表的长度达到2*n(所有0和1都用完了),该函数将返回列表。

import random

def pseudo_rand(n):
    left = {0: n, 1: n} # keep track of how many 1s or 0s you can still use
    out = []
    while len(out) < n*2:
        i = random.randint(0,1) # select 0 or 1 randomly
        if not left[i]: # if have already used up all the 0s or 1s, use the other one instead
            i = 1-i
        possible_pos = list(range(len(out)+1)) # make a list of possible indexes to insert i
        while possible_pos:
            pos = random.choice(possible_pos)
            bottom = max(pos-2, 0)
            top = pos+2
            dz = out[bottom:top] # danger zone: range to inspect to see if we can insert i at position pos  
            if not any(i == dz[j] and i == dz[j-1] for j in range(1, len(dz))): # if inserting i at position pos won't violate the 'no 3 in a row constraint'
                out.insert(pos, i)
                left[i] -= 1
                break
            else: # otherwise don't consider this position anymore
                possible_pos.remove(pos) 
    return out

一些例子:

>>> pseudo_rand(24)
[1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]

>>> pseudo_rand(5)
[1, 0, 0, 1, 0, 0, 1, 1, 0, 1]

答案 1 :(得分:1)

天真的解决方案:

import random

def gen_list():
    bin_list=[]
    count=(0,0)
    while len(bin_list)<48:
        choice=random.randint(0,1)
        if choice==0:
            bin_list.append(0)
            count=(count[0]+1,count[1])
        else:
            bin_list.append(1)
            count=(count[0],count[1]+1)
        violates_run_constraint=(len(bin_list)>3) and (bin_list[-1]==bin_list[-2]==bin_list[-3])
        if violates_run_constraint:
            return ([],())
    return (bin_list,count)


bin_list,count=gen_list()
while(bin_list==[] or count!=(24,24)):
    bin_list,count=gen_list()
print(bin_list,count)

gen_list()创建一个长度为48的列表,该列表仅包含1和0,是随机选择的。它还跟踪使用了多少个1和0,并将此信息作为元组返回。

但是,它也会失败并违反约束。如果这样做,它只会返回一个空列表。

外部循环将生成列表,直到得到一个不受约束的列表为止,并且生成的列表中的1和0的数量等于24。

可能不是最有效的解决方案,但肯定可以工作,并且很多比我预期的要快。

示例输出:

[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] (24, 24)

[1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0] (24, 24)