2n用户的所有可能分配向量

2 投票
5 回答
1788 浏览
提问于 2025-04-18 07:11

我想写一个函数来计算2n个用户的所有可能分组方式,其中n个用户被分到组0(对照组),n个用户被分到组1(实验组)。

我试过用递归的方法,下面是我的尝试,但我知道这样是行不通的(我觉得应该有C(2n,n)种分组方式,对吧?)

有没有什么好的想法?

谢谢。

def algo(n):
   T = list();
   if n>=2 :
      for j in range(len(algo(n-1))/2):
         T.append([0,1]+algo(n-1)[j]);
      for j in range(len(algo(n-1))/2):
         T.append([1,0]+algo(n-1)[j]);
      for j in (len(algo(n-1)/2):(len(algo(n-1)*(3/4)):
         T.append([0,0]+algo(n-1)[j]);    
      for j in range(len(algo(n-1))):
         T.append([1,1]+algo(n-1)[j]);
   if n==1 :
      T=[[0,1],[1,0],[0,0],[1,1]];
   return T

5 个回答

0

你可以试着像这样来完成你的作业:

from itertools import product

n=3
values = [0,1]
ref_list = [values]*2*n

for p in product(*ref_list):
    if sum(p) == n:
        print(p)
0

使用二进制 :)

def binSum(n):
    st = str(bin(n))
    sum = 0;
    i = 2
    while i < len(st):
        sum += int(st[i])
        i += 1
    return sum

def assignmentVectors(n):
    for i in range(0,pow(2,n)-1):
        if binSum(i) == n/2:
            print ('{:0'+str(n)+ 'b}').format(i)

assignmentVectors(4)
assignmentVectors(6)
assignmentVectors(8)
0

递归的方法效果非常好:

def iter_fun(sum, deepness, myString, currentI, Total):
    if deepness == 0:
    print myString
    else:    
    for i in xrange(currentI+1, Total): 
        iter_fun(sum + 1,deepness - 1,myString + str(i),i,Total) 

def enumeratePartition(digits, Tot):
    iter_fun(0,digits,"",-1,Tot) 


enumeratePartition(4,8)
1

想法 1:使用Python中已有的函数

想法 2:使用递归的方法来实现。

def allSamples(k,n):
    # choose k elements in candidate lists from [0,...,n-1] with length n
    # input:
        # k: number of choosed elements 
        # n: candidate list length
    # output: 
        # list of all possible assignments

    allC = []

    if k == 1:
        for i in range(n):
            assignment = [0]*n
            assignment[i] = 1
            allC.append(assignment)
    elif n == k:
        assigment = [1]*n
        allC = [assigment]
    else:
        pl = n - k + 1
        for i in range(pl):
            assignment = [0]*(i+1)
            assignment[i] = 1
            for c in allSamples(k-1,n-i-1):
                allC.append(assignment+c)
    return allC

k = 2
n = 2*k
print allSamples(k,n)
4
import itertools

def split_users(users_list):
    users = set(users_list)
    for comb in itertools.combinations(users, int(len(users)/2)):
        control = set(comb)
        treatment = users - control
        yield control, treatment

users = {"A", "B", "C", "D", "E", "F"}

for control, treatment in split_users(users):
    print "Control", control, "treatment", treatment

简单来说,split_users 是一个生成器函数,它会从用户列表中取出所有可能的组合,数量是用户总数的一半,然后把这些组合分配到 control 组中,其余的用户则被归为 treatment 组。

想了解更多细节,可以参考 setitertoolsyield 的相关文档。

另外,请注意,你所说的“用户”必须是可哈希的。如果用户是用自定义类表示的,你需要定义 __hash____eq__ 这两个函数。

撰写回答