- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想有效地生成一个(封闭)范围内的唯一(非重复)整数的随机样本 [0, rnd_max]
,范围内的每个数字都可以选择,并且每个都与样本权重相关联(权重越大,选择该数字的可能性就越大,下一个被选择的概率恰好是 weight[i]/sum(weight[not_taken])
如果它还没有被纳入样本)。
我看到 C++ 有 std::discrete_distribution
可以生成随机加权整数,但是如果我用它来生成随机整数并丢弃重复的整数,当要获取的样本相对于长度来说很大时在可能的范围内,将会有很多已经采集的失败样本,导致程序效率极低。我不清楚 Floyd 算法是否对样本权重 (https://math.stackexchange.com/questions/178690/whats-the-proof-of-correctness-for-robert-floyds-algorithm-for-selecting-a-sin) 的情况有一些扩展 - 我个人想不出一个。
也可以例如使用 std::discrete_distribution
将权重降为零,或执行部分加权洗牌,如以下答案:C++. Weighted std::shuffle - 但在该答案中,std::discrete_distribution
在每次迭代时重新生成,因此运行时间变为二次方(它需要循环遍历每次传递给它的权重)。
想知道 C++ 中唯一整数的有效加权随机样本是什么,它适用于不同的样本大小(例如,可用范围内的样本数的 1% 到 90%)。
#include <vector>
#include <random>
#include <algorithm>
int main()
{
size_t rnd_max = 1e5;
size_t ntake = 1e3;
unsigned int seed = 12345;
std::mt19937 rng(seed);
std::gamma_distribution<double> rgamma(1.0, 1.0);
std::vector<double> weights(rnd_max);
for (double &w : weights) w = rgamma(rng);
std::vector<int> chosen_sample(ntake);
// sampler goes here...
return 0;
}
最佳答案
使用扩充二叉搜索树可以很好地解决这个问题。它给出了一个时间复杂度为 O(k log n) 的随机采样 k 个元素的算法。
思路是这样的。假设您将所有元素按排序顺序存储在一个数组中,每个元素都标有其权重。然后,您可以按如下方式(低效地)解决此问题:
如果你按上面提到的方式实现它,每次选择一个随机元素的过程都将花费 O(n) 的时间:你必须遍历数组的所有元素,然后在你选择它之后从某处删除一个元素.那不是很好;整体运行时间为 O(kn)。
我们可以通过以下方式稍微改进这个想法。当存储数组中的所有元素时,让每个元素都存储其实际权重和所有在它之前的元素的组合权重。现在,要找到您要采样的元素,您不需要使用线性搜索。您可以改为对数组使用 二分搜索 以在时间 O(log n) 中定位您的元素。但是,这种方法的总体运行时间仍然是每次迭代的 O(n),因为这是删除您选择的元素的成本,所以我们仍然处于 O(kn) 范围内。
但是,如果您不将元素存储在排序的数组中,其中每个元素存储它之前的所有元素的权重,而是在平衡二分查找中树,其中每个元素存储其左子树中所有元素的权重,您可以模拟上述算法(二分搜索被替换为遍历树)。此外,这样做的好处是可以在 O(log n) 时间内从树中删除一个元素,因为它是一个平衡的 BST。
(如果您好奇如何通过遍历找到您想要的元素,请快速搜索“order statistics tree”。这里的想法本质上是这个想法的概括。)
按照@dyukha 的建议,您可以通过在时间为 O(n) 的项目中构建一个完美平衡的树来获得每个操作的 O(log n) 时间(实际上不必为此对项目进行排序工作的技术 - 你知道为什么吗?),然后每次你需要删除一些东西时使用标准的树删除算法。这给出了 O(k log n) 的整体解决方案运行时间。
关于C++ 具有权重的随机非重复整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57599509/
我有几个系统,其中包含用户表以及某种形式的业力/权重/声誉。有时是用户发布的帖子数量,有时是用户在网站上的所有事件中收到的赞成/反对票数。 USER { id int name str
我需要能够使用填充的相对大小 - 根据设备的分辨率和 dpi 变大或变小。 例如,如果我的 View 宽度为 100 像素,我希望左侧填充 10 像素,右侧填充 10 像素。但是,如果它在更高密度的屏
我目前正在使用由大约 10 个字段组成的 Solr 索引数据。当我执行搜索时,我希望某些字段的权重更高。谁能帮我指出正确的方向? 例如,在所有字段中搜索“超人”等术语时,应在“Description”
我正在使用 igraph 模拟网络随时间的变化在 r并且我正在寻找一种有效且可扩展的方式来对此进行编码以用于业务。 网络变化的主要驱动因素是: 新增节点 新领带 新节点权重 在第一阶段,在 100 个
我一直在寻找一种使用OpenVINO框架上的C++ API获取网络每一层权重/参数和偏差张量的方法。我在文档中找不到任何内容,在示例中也找不到任何示例。我如何提取这些张量? 谢谢, 塞萨尔 编辑: 分
我的问题与 PHP Memcache 扩展的 addServer 函数中的“weight”参数有关。 在过去的几个月里,我一直在为所有服务器使用“weight = 1”。我现在正在尝试应用以下配置以最
我应该使用哪种数据结构来保持元素按给定权重排序?我需要在集合中添加元素,其中每个元素都会生成特定的权重,但该权重不包含(也不计算)在元素本身内部;它是由元素之外的其他人计算的。而且,权重不需要存储(但
我正在尝试在 keras/tensorflow 中使用具有多个类的焦点损失,这导致使用我猜的分类焦点损失。我找到了一些实现here和 there或there 。 据我了解,焦点损失中的参数a主要用于二
我有一个像这样的 Pandas 数据框: df = pd.DataFrame({'id': [121, 34324, 111, 12, 45, 232], 'weight'
我有一个带有输出神经元的神经网络,我想在软最大化之前使用经过训练的权重进行线性缩放。 我有 10 个输出,我想要 10 个权重,在输出被软最大化之前乘以每个输出。因此每个输出的权重为 1。 但我不断收
我有这样的布局: 我希望它看起来像: TextView - 宽度的 40%,带 ImageView 的布局
这让我彻底疯了。我想在 android 中使用有点复杂的布局。我正在尝试使用权重而不是固定事物的大小。也许我应该放弃…… 这是我想做的: 我想要 3 个 ScrollView (里面有 TextVie
我正在尝试开发类似于网格但使用 LinearLayout。我想在单行中有 3 张图像和图像后的确切底部文本。 我尝试过的: LinearLayout layout = new LinearLayout
我想在同一行添加一个 EditText 和一个 Button,我想将 80% 的行给 editText,20% 给 Button。 这是我的代码:
我有一个 mysql 表,其中存储一列(称为 tickets),并且 tickets 值可以是任意数字。 我想要做的是有一个mysql查询,从列中选择所有行,按降序对它们进行排序,然后使用PHP对查询
我搜索了一段时间,但结果让我很困惑,因为我对 MySQL 还很陌生。 我有一个包含这 4 列的表:AUTO_INCREMENT ID、NAME、TYPE、CHANCE 所以行看起来像这样: 1, NO
我不完全是 JS 专业人士,虽然不漂亮或高效,但这是有效的。 实际上,我在表单中有重复的字段组,并允许用户根据需要将数据从第一个字段复制到所有 5 个字段。 如何使这段代码更高效? function
我正在使用xgboost库来训练二元分类器。我想通过向权重添加噪声(例如集合中树的叶节点的值)来防止训练算法的数据泄漏。为此,我需要检索每棵树的权重并修改它们。 我可以通过在 Booster 对象上使
我正在尝试让 LinearLayout 中的 View 填充宽度。我尝试使用 LayoutParams 设置它,但它给了我一个错误: 我的代码: EditText et = new EditText(
我想改变 ScrollView 的权重,但找不到实现它的方法。 这是我的 XML: **other layout.. 从代码中只能设置scrollView的高度或者宽度,weigh
我是一名优秀的程序员,十分优秀!