c++ - 加权随机数

标签 c++ boost random

我正在尝试实现加权随机数。我目前只是用头撞墙,无法弄清楚这一点。

在我的项目(德州扑克手牌范围、主观全押权益分析)中,我使用 Boost 的随机函数。因此,假设我想选择 1 到 3 之间的随机数(即 1、2 或 3)。 Boost 的梅森扭曲生成器对此很有魅力。但是,我希望对选秀权进行加权,例如如下所示:

1 (weight: 90)
2 (weight: 56)
3 (weight:  4)

Boost 有某种功能吗?

最佳答案

有一个简单的算法可以随机挑选一个项目,其中项目具有单独的权重:

1)计算所有权重的总和

2) 选择一个大于或等于 0 且小于权重之和的随机数

3) 一次检查一个元素,从随机数中减去它们的重量,直到得到随机数小于该元素重量的元素

说明这一点的伪代码:

int sum_of_weight = 0;
for(int i=0; i<num_choices; i++) {
   sum_of_weight += choice_weight[i];
}
int rnd = random(sum_of_weight);
for(int i=0; i<num_choices; i++) {
  if(rnd < choice_weight[i])
    return i;
  rnd -= choice_weight[i];
}
assert(!"should never get here");

这应该很容易适应您的 boost 容器等。

<小时/>

如果您的权重很少改变,但您经常随机选择一个,并且只要您的容器存储指向对象的指针或长度超过几十个项目(基本上,您必须进行分析才能知道这是否有帮助)或阻碍),然后有一个优化:

通过存储每个项目的累积重量总和,您可以使用 binary search拾取与拾取重量相对应的元素。

<小时/>

如果您不知道列表中的项目数,那么有一个非常简洁的算法,称为 reservoir sampling可以调整为加权。

关于c++ - 加权随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59454731/

相关文章:

c++ - 使用 volatile 标准模板对象的方法

c++ - 如何将 boost::serialize 成 sqlite::blob?

java - java 中的 Random.nextBytes(bytes[]) 行为

c++ - 将使用双向 popen() 的 C++ 代码移植到 POSIX 的最佳方法

我无法解决的 C++ 长错误消息

c++ - 理解 8 皇后拼图的对角搜索

c++ - 使用 boost 线程库打印

c++ - Boost:位置参数无法识别的选项

JavaScript Math.random 重复生成

random - 如何使用 netlogo 生成 0.3 < X < 0.7 范围内的数字