Algorithm 生成总和为n的随机数
如何生成1到n个随机数(大于0的正整数),其总和正好为n n=10时的示例结果:Algorithm 生成总和为n的随机数,algorithm,random,Algorithm,Random,如何生成1到n个随机数(大于0的正整数),其总和正好为n n=10时的示例结果: 10 2,5,3 1,1,1,1,1,1,1,1,1,1 1,1,5,1,1,1 每个排列都应该有相同的发生概率,但是,我不需要它在数学上精确。如果由于模误差,概率不一样,我不在乎 是否有一个用于此的go-to算法?我只发现数值的数量是固定的算法(即,给我m个随机数,加起来等于n)。使用模 这将使你的一天: #include <stdio.h> #include <stdlib.h> #i
10
2,5,3
1,1,1,1,1,1,1,1,1,1
1,1,5,1,1,1
每个排列都应该有相同的发生概率,但是,我不需要它在数学上精确。如果由于模误差,概率不一样,我不在乎
是否有一个用于此的go-to算法?我只发现数值的数量是固定的算法(即,给我m个随机数,加起来等于n)。使用模
这将使你的一天:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(0));
int n=10;
int x=0; /* sum of previous random number */
while (x<n) {
int r = rand() % (n-x) + 1;
printf("%d ", r);
x += r;
}
/* done */
printf("\n");
}
将数字n想象成一条由n个相等的、不可分割的部分组成的线。您的数字是这些部分的长度,这些部分的总和为整体。可以在任意两个截面之间剪切原始长度,也可以不剪切 这意味着存在n-1潜在切点 选择一个随机的n-1-位数字,即介于0和2^(n-1)之间的数字;它的二进制表示形式告诉您在哪里剪切
0 : 000 : [-|-|-|-] : 1,1,1,1
1 : 001 : [-|-|- -] : 1,1,2
3 : 011 : [-|- - -] : 1,3
5 : 101 : [- -|- -] : 2,2
7 : 111 : [- - - -] : 4
等等
python-3中的实现
import random
def perm(n, np):
p = []
d = 1
for i in range(n):
if np % 2 == 0:
p.append(d)
d = 1
else:
d += 1
np //= 2
return p
def test(ex_n):
for ex_p in range(2 ** (ex_n - 1)):
p = perm(ex_n, ex_p)
print(len(p), p)
def randperm(n):
np = random.randint(0, 2 ** (n - 1))
return perm(n, np)
print(randperm(10))
您可以通过为小型n
test(4)
输出:
4 [1, 1, 1, 1]
3 [2, 1, 1]
3 [1, 2, 1]
2 [3, 1]
3 [1, 1, 2]
2 [2, 2]
2 [1, 3]
1 [4]
@塞加约兹:我也想到了这个算法,但是,它看起来好像偏离了“每个排列的概率相同”,不是吗?很容易有10个以上的排列,但“10”的概率为1/10。(我知道,我说过它不必精确到数学上,但也不应该太离谱)只是为了澄清一下——你说的是“数字”,但你的例子都是整数。是否排除浮点解决方案?允许负值吗?零呢?我不确定为什么人们投票认为这个问题“太广泛”,我如何才能改进这个问题?请留言,谢谢!没有尝试,也没有标记来指明你写这篇文章的语言。对我来说,这看起来更像是一个问题,而不是一个编程问题。@TobySpeight:最后我想要C代码,但我忽略了C标记,因为我对算法感兴趣,而不是具体的实现。算法问题不是StackOverflow的一部分吗?至于尝试,如果我自己找不到方法,我就无权在这里发帖了?谢谢你的解释,这是一个非常好的答案。我们不需要一次生成决策树的所有n个比特——如果我们有一个随机比特源,我们可以根据需要获取它们。这可以避免我们不会用于算术的庞大算术数字的开销。我喜欢你解决问题的方式,也非常喜欢你演示示例的方式。这似乎偏向于较短的序列;示例输出中只有一个以
1
开头,但如果从所有可能性中公平选择,我们预计其中大约一半以1
开头。
4 [1, 1, 1, 1]
3 [2, 1, 1]
3 [1, 2, 1]
2 [3, 1]
3 [1, 1, 2]
2 [2, 2]
2 [1, 3]
1 [4]