3

给定一个整数范围 R = [a, b](其中 a >=0 和 b <= 100),R 中的一个偏置整数 n,以及一些偏差 b,我可以使用什么公式将随机数生成器偏向 n?

因此,例如,如果我有 1 到 10 的数字并且我没有指定偏差数字,那么理论上我应该有相同的机会随机抽取其中一个。

但是如果我确实给出了一个特定的偏差数(比如 3),那么数字生成器应该比其他数字更频繁地绘制 3 a。

如果我在偏置数之外指定一个偏差,比如说 2,那么数字生成器应该比从 6 到 10 更频繁地从 1 到 5 绘制。

我可以使用什么算法来实现这一点?

如果它更容易/更难,我正在使用 Ruby。

4

3 回答 3

3

我认为最简单的方法是从具有所需属性的正态(又名高斯)分布中进行采样,然后转换结果:

  • 生成具有给定均值和 sd 的正常值
  • 四舍五入到最接近的整数
  • 如果超出给定范围(正常可以在从 -infinity 到 -infinity 的整个范围内生成值),丢弃并重复

如果您需要从制服生成法线,最简单的变换是“ box-muller ”。

您可能需要担心一些细节。特别是,box muller 的范围有限(它永远不会产生极不可能的值)。因此,如果您给出一个非常窄的范围,那么您将永远无法获得完整的值范围。其他转换不受限制 - 我建议使用 ruby​​ 提供的任何东西(寻找“正常”或“高斯”)。

另外,请注意对值进行四舍五入。例如,2.6 到 3.4 应该都变成 3。如果您简单地丢弃小数(因此 3.0 到 3.999 变为 3),您将有偏见。

如果您真的关心效率,并且不想丢弃价值,您可以简单地发明一些东西。一种作弊方法是将统一变量与偏差值混合(例如,9/10 倍生成统一,1/10 倍返回 3)。在某些情况下,您只关心样本的平均值,这就足够了。

于 2012-05-07T16:40:38.723 回答
0

对于第一部分“但是如果我确实给出了一个特定的偏差数(比如 3),那么数字生成器应该比其他数字更频繁地绘制 3 a。”,一个非常简单的解决方案:

def randBias(a,b,biasedNum=None, bias=0):
   x = random.randint(a, b+bias)
   if x<= b:
       return x
   else:
       return biasedNum

对于第二部分,我会说这取决于任务。如果您需要从同一分布中生成十亿个随机数,我会明确计算这些数字的概率并使用加权随机数生成器(请参阅随机加权选择

于 2012-05-07T17:17:27.080 回答
0

如果您想要一个单峰分布(其中偏差仅集中在您的数字范围的一个特定值中,例如,正如您所说的 3),那么 andrew cooke 提供的答案是好的——主要是因为它允许您非常准确地微调偏差。

但是,如果您希望做出几个偏差——例如,您想要一个三峰分布,数字 a、(a+b)/2 和 b 比其他数字更频繁,那么您最好实施加权随机选择。

在 StackOverflow 最近的一个问题中给出了一个简单的算法;它的复杂性是线性的。使用这样的算法,您只需维护一个列表,初始包含 {a, a+1, a+2,..., b-1, b}(大小为 b-a+1),当您需要要添加对 X 的偏见,您可以将 X 的多个副本添加到列表中——这取决于您想要偏见的程度。然后从列表中选择一个随机项目。

如果您想要更高效的方法,最有效的方法称为“别名方法”,它由 Denis Bzowy 在 Python 中非常清楚地实现;一旦你的数组被预处理,它就会在恒定时间内运行(但这意味着一旦你完成了预处理,你就不能再更新偏差了——或者你会重新处理表格)。

这两种技术的缺点是,与高斯分布不同,偏向 X,也不会偏向 X-1 和 X+1。要模拟这种效果,你必须做一些事情,比如

def addBias(x, L):
   L = concatList(L, [x, x, x, x, x])
   L = concatList(L, [x+2])
   L = concatList(L, [x+1, x+1]) 
   L = concatList(L, [x-1,x-1,x-1])
   L = concatList(L, [x-2])
于 2012-05-08T21:14:40.730 回答