从范围中选择K个唯一的随机数,其总和等于S.

时间:2016-01-13 10:53:11

标签: algorithm random

我有一个范围

R = {0, ..., N}

我希望获得总和等于K的{​​{1}}个元素,但这些元素应该随机选择。

因此,一种简单的强力方法是确定包含S个数字的所有元素组合,从而产生K并随机选择其中一个组合。

我正在考虑一个递归解决方案,其中选择一个随机数,然后问题减少到找到(K-1)随机数,其总和等于(S-K0),但这不需要在解决方案中产生。

有更好的方法吗?

样本将是:

S

2 个答案:

答案 0 :(得分:1)

一般情况下,如果K很大(那么N也是),而S不是太少,那是不可预测的,因为有两种组合。

蛮力:尝试每种组合。你肯定会找到一个解决方案,如果有一个解决方案,但是如果有超过1 Md或者有点,那么几乎不可能全部列出它们。

您的算法:

要随机选择,你的算法是可以的:随机取一个数字,然后另一个,......

但是你做了一个假设:你选择的数字存在一个解决方案:你不知道。

那又怎样?如果统计上存在许多解决方案,你可以找到它,或许,或者可能不是

一些小道:

1使用S / K

如果每个数字< S / K,这是不可能的。

如果每个数字&gt; S / K,这是不可能的。

所以我们假设有数字&lt; S / K等其他&gt; S / K

2只保留数字&lt; S,如果S很小的话,非常有趣。

3个想法:如果S很大,数字很少,你就有机会存在很多组合。

算法的想法

1随机取一个数字N1

如果N1 <2,则

2。 S / K,取另一个N2> S /ķ

3计算N1 + N2:如果&lt; 2.S / K取另一个N3> S / K,如果没有

每步重复4次:如果总和&lt; n S / K采取另一个&gt; S / K,如果没有

5通过将S / K替换为(S-sum N1,N2,...)/(K-n),可以获得更好的精度

如果在某一步你找不到任何号码,那么回溯

希望有所帮助

答案 1 :(得分:1)

我将从Dirichlet发行(https://en.wikipedia.org/wiki/Dirichlet_distribution)开始。使用它,您可以在(0..1)分布式随机数X i 中均匀采样,使得Sum i X i = 1。

对于S <= N,很容易看到超出S的抽样是无用的,应该被彻底拒绝。

因此,与接受/拒绝相结合,就行了

  • 将时间间隔[0 ... 1]划分为S(如果允许为0,则为S+1)相等的容器。
  • 来自Dirichlet发行的样本K
  • 将采样数映射到bin索引,因此您现在已经采样了整数 全部低于或等于S且总和等于S
  • 如果所有整数都不同,请接受抽样,否则拒绝抽样并转到步骤2