#include <iostream>
#include <random>
#include <iterator>
#include <ctime>
#include <type_traits>
#include <cassert>
int main()
{
// Set up distribution
double interval[] = {1, 2, 3, 4};
double weights[] = { .90, .56, .04};
std::piecewise_constant_distribution<> dist(std::begin(interval),
std::end(interval),
std::begin(weights));
// Choose generator
std::mt19937 gen(std::time(0)); // seed as wanted
// Demonstrate with N randomly generated numbers
const unsigned N = 1000000;
// Collect number of times each random number is generated
double avg[std::extent<decltype(weights)>::value] = {0};
for (unsigned i = 0; i < N; ++i)
{
// Generate random number using gen, distributed according to dist
unsigned r = static_cast<unsigned>(dist(gen));
// Sanity check
assert(interval[0] <= r && r <= *(std::end(interval)-2));
// Save r for statistical test of distribution
avg[r - 1]++;
}
// Compute averages for distribution
for (double* i = std::begin(avg); i < std::end(avg); ++i)
*i /= N;
// Display distribution
for (unsigned i = 1; i <= std::extent<decltype(avg)>::value; ++i)
std::cout << "avg[" << i << "] = " << avg[i-1] << '\n';
}
#include <random>
#include <vector>
std::vector<double> weights{90,56,4};
std::discrete_distribution<int> dist(std::begin(weights), std::end(weights));
std::mt19937 gen;
gen.seed(time(0));//if you want different results from different runs
int N = 100000;
std::vector<int> samples(N);
for(auto & i: samples)
i = dist(gen);
//do something with your samples...
weight = rand() % 10;
switch( weight ) {
case 0:
randomNumber = 1;
break;
case 1:
case 2:
case 3:
randomNumber = 2;
break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
randomNumber = 3;
break;
}
highest = [None, 0]
for p in choices:
score = math.floor(random.random() * p[1])
if score > highest[1]:
highest[0] = p
highest[1] = score
print(highest)
9条答案
按热度按时间a11xaf1n1#
有一个简单的算法用于随机挑选物品,其中物品具有各自的权重:
1)计算所有权重之和
2)选择一个大于或等于0且小于权重之和的随机数
3)我一次一个地检查这些项目,从你的随机数中减去它们的权重,直到你得到随机数小于该项目权重的项目
伪代码说明了这一点:
这应该是直接适应您的升压容器等。
如果你的权重很少改变,但你经常随机选择一个,并且只要你的容器存储指向对象的指针,或者长度超过几十个项目(基本上,你必须分析以知道这是帮助还是阻碍),那么就有一个优化:
通过在每个项目中存储累计重量总和,您可以使用binary search来挑选与挑选重量对应的项目。
如果你不知道列表中的项目数,那么有一个非常简洁的算法,叫做reservoir sampling,它可以用来加权。
nhhxz33t2#
更新了一个老问题的答案。您可以在C++11中使用std::lib:
系统上的输出:
请注意,上面的大部分代码只是用于显示和分析输出。实际生成只是几行代码。输出表明请求的“概率”已经获得。您必须将请求的输出除以1.5,因为这是请求的总和。
2j4z5cfb3#
如果权重的变化比绘制的要慢,C++11
discrete_distribution
将是最简单的:注意,c11
discrete_distribution
在初始化时计算所有的累积和,通常,你需要这样做是因为它加快了一次O的采样时间(N)成本。但对于快速变化的分布,这将招致繁重的计算(和内存)成本。例如,如果权重表示有多少项目,每次你画一个,你删除它,你可能会想要一个自定义的算法。Will的答案https://stackoverflow.com/a/1761646/837451避免了这种开销,但是由于它不能使用二进制搜索,所以提取速度比C11慢。
要了解它是如何做到这一点的,您可以查看相关行(在我的Ubuntu 16.04 + GCC 5.3安装中为
/usr/include/c++/5/bits/random.tcc
):brqmpdu14#
当我需要给数字加权的时候,我会用一个随机数作为权重。
例如:我需要生成从1到3的随机数,权重如下:
然后我使用:
这样,随机地,它有10%的概率是1,30%的概率是2,60%的概率是3。
你可以根据需要玩它。
希望我能帮到你,祝你好运!
wmtdaxz35#
为所有可以拾取的项目构建一个包(或std::vector)。
确保每个项目的数量与您的权重成比例。
示例:
因此,有一个袋子有100件物品,其中60件1,35件2和5件3。
现在对行李进行随机排序(std::random_shuffle)
按顺序从袋子中取出元件,直到袋子空了。
空袋后,重新随机分配袋子并重新开始。
r6hnlfcb6#
在[0,1)上选择一个随机数,它应该是提升RNG的默认运算符()。选择累积概率密度函数〉=该数的项目:
其中random 01()返回一个双精度值〉=0且〈1。注意,上面的例子并不要求概率之和为1;它会让你正常化。
p只是一个为集合[开始,end]中的某个项指定概率的函数,如果只有概率序列,可以省略它(或使用恒等式)。
5w9g7ksd7#
这是我对"加权随机数"的理解,我最近一直在使用它。(代码用Python编写,但也可以用其他语言实现)
假设你想随机挑选一个人,但他们被选中的机会并不相等。你可以给每个人一个"权重"或"机会"值:
您可以使用它们的权重来计算每个选项的得分,然后找到得分最高的选项
对于Ade来说,他们能得到的最高分是60分,最高分是50分,以此类推,这意味着Ade比其他人有更高的机会得到最高分。
您可以使用任何范围的权重,差异越大,分布的偏斜程度越大。例如,如果Ade的权重为1000,则几乎总是选择他们。
测试
一个二个一个一个
问题
看起来选民越多,结果就越容易预测。
希望这能给人一个想法...
oaxa6hgo8#
我刚刚通过“will“实现了给定的解决方案
x4shl7ld9#
例如,在用于该指数的权重向量中生成随机指数可以这样完成:
由于我们使用
(no of elements) = almost (current no of elements) * (mean weight)
构造另一个向量,因此这种方法现在可能适用于处理大数据。