"切片"一个数字分成三个随机数

时间:2014-10-22 23:20:21

标签: python random numbers slice

我需要生成一个充满三个"随机"的文件。每行的值(10行),但这些值总和必须等于15.

结构是:" INDEX A B C"。

示例:

1 15 0 0
2 0 15 0
3 0 0 15
4 1 14 0
5 2 13 0
6 3 12 0
7 4 11 0
8 5 10 0
9 6 9 0
10 7 8 0

3 个答案:

答案 0 :(得分:4)

如果你想避免需要创建(或遍历)满足排列的完整空间(对于大N很重要),那么你可以解决这个问题顺序样本。

我的第一种方法是从[0,N]统一绘制一个值,称之为x。然后从[0,N - x]统一绘制一个值并将其称为y,然后设置z = N - x - y。如果你随后洗牌这三个,你会从解决方案的空间中得到一个合理的抽签,但它不会完全统一。

例如,考虑N=3的位置。然后,(3,0,0)的某些排列的概率是1/4,即使它只是10个可能的三元组中的一个。因此,此权限值包含高最大值

通过对x y条件x可能的值进行比例采样,可以完美地抵消此效果。x例如,如果N恰好是y,则x只有1个兼容值,但如果Pr(X=x)为0,则有4个兼容值,即0到3。

换句话说,让(N-x+1)/sum_i(N-i+1) iN从0到Pr(Y=y | X=x)。然后让sum(N-i+1 for i in range(0, N+1))在[0,N-x]上保持一致。

这适用于P(X,Y)= P(Y | X = x)* P(X)= 1 /(N-x + 1)* [N-x + 1] / sum_i(N-对于每个候选三元组,i + 1),被认为是均匀的,1 / sum_i(N-i + 1)。

请注意N给出了将3个非负整数相加以获得import random from collections import Counter def discrete_sample(weights): u = random.uniform(0, 1) w_t = 0 for i, w in enumerate(weights): w_t += w if u <= w_t: return i return len(weights)-1 def get_weights(N): vals = [(N-i+1.0) for i in range(0, N+1)] totl = sum(vals) return [v/totl for v in vals] def draw_summing_triplet(N): weights = get_weights(N) x = discrete_sample(weights) y = random.randint(0, N-x) triplet = [x, y, N - x - y] random.shuffle(triplet) return tuple(triplet) 的不同方法的数量。我不知道这个的好证据,如果有人在评论中添加一个,我会很高兴!

这是一个以这种方式进行采样的解决方案:

foo = Counter(draw_summing_triplet(3) for i in range(10**6))
print foo

Counter({(1, 2, 0): 100381, 
         (0, 2, 1): 100250, 
         (1, 1, 1): 100027, 
         (2, 1, 0): 100011, 
         (0, 3, 0): 100002, 
         (3, 0, 0): 99977, 
         (2, 0, 1): 99972,
         (1, 0, 2): 99854, 
         (0, 0, 3): 99782, 
         (0, 1, 2): 99744})

在评论我的原始答案并提供良好反馈的评论中,@ DSM给予了很多赞誉。

在这种情况下,我们可以像这样测试采样器:

{{1}}

答案 1 :(得分:2)

如果数字可以通过任何只使用组合:

from itertools import combinations
with open("rand.txt","w") as f:
    combs = [x for x in combinations(range(16),3) if sum(x ) == 15 ][:10]   
    for a,b,c in combs:
        f.write("{} {} {}\n".format(a,b,c))

答案 2 :(得分:0)

这对我来说很简单,并且它使用了随机模块。

import random

def foo(x):
    a = random.randint(0,x)
    b = random.randint(0,x-a)
    c = x - (a +b)

    return (a,b,c)

for i in range(100):
    print foo(15)