随机生成[0,n)中不重复的m个数。

 class Random {
public:
Random(int n, int m):n(n), m(m) {}
void generate() {
srand(time(NULL));
for (int i = ; i < n; ++i) data.push_back(i);
for (int i = ; i < m; ++i) swap(data[i], data[i + rand() % (n - i)]);
} void increase() {
data.push_back(n++);
int i = rand() % n;
swap(data[i], data[n - ]);
} void print() const {
for (int i = ; i < m; ++i)
cout << data[i] << " ";
cout << endl;
}
private:
int n;
int m;
vector<int> data;
};

Line 7, 第i个元素会和第从[i, n)中找一个元素交换。可以证明每个数被选择在第k个位置上的概念为1/n。被选择的概念为m/n。

比如0被放在data[1]这个位置的概率,等于0没有被放在第一个位置的概率*0放在第二个位置的概率,也就是(1-1/n)*1/(n-1)=1/n。

依此类似。

最终前m个数就是不重复随机数。

如果data是不断递增的,也就是newN = n + 1,怎么随机选择k个数? 只要将data[newN - 1]和前面的数随机交换就可以了,O(1)的更新。

对于第newN个数,它被选上的概率是1/newN.

其他数被选上的概率 =(它之前被选在m个数里面的概率)*(它在newN下没有被交换出这m个数的概率)

=(它之前被选在m个数里面的概率)*(第newN个数和其他数交换的概率)=(1/n)*(n/newN)=1/newN。

Select a random number from stream, with O(1) space

Given a stream of numbers, generate a random number from the stream. You are allowed to use only O(1) space and the input is in the form of stream, so can’t store the previously seen numbers.

So how do we generate a random number from the whole stream such that the probability of picking any number is 1/n. with O(1) extra space? This problem is a variation of Reservoir Sampling. Here the value of k is 1.

看完geeksforgeeks上面的解释。

重写了一遍。

     void increase() {
data.push_back(n++);
int i = rand() % n;
//swap(data[i], data[n - 1]);
if (i < m) data[i] = data[n - ];
}

Algorithm | Random的更多相关文章

  1. 机器学习算法 --- Pruning (decision trees) & Random Forest Algorithm

    一.Table for Content 在之前的文章中我们介绍了Decision Trees Agorithms,然而这个学习算法有一个很大的弊端,就是很容易出现Overfitting,为了解决此问题 ...

  2. Graphs and Minimum Cuts(Karger's Min-Cut Algorithm)

    Graphs  Two ingredients 1. vertices (nodes) v 2. edges(undirected or directed) Examples: road networ ...

  3. ML—随机森林·1

    Introduction to Random forest(Simplified) With increase in computational power, we can now choose al ...

  4. TensorFlow利用A3C算法训练智能体玩CartPole游戏

    本教程讲解如何使用深度强化学习训练一个可以在 CartPole 游戏中获胜的模型.研究人员使用 tf.keras.OpenAI 训练了一个使用「异步优势动作评价」(Asynchronous Advan ...

  5. DRL 教程 | 如何保持运动小车上的旗杆屹立不倒?TensorFlow利用A3C算法训练智能体玩CartPole游戏

    本教程讲解如何使用深度强化学习训练一个可以在 CartPole 游戏中获胜的模型.研究人员使用 tf.keras.OpenAI 训练了一个使用「异步优势动作评价」(Asynchronous Advan ...

  6. cvpr2015papers

    @http://www-cs-faculty.stanford.edu/people/karpathy/cvpr2015papers/ CVPR 2015 papers (in nicer forma ...

  7. 从Random Walk谈到Bacterial foraging optimization algorithm(BFOA),再谈到Ramdom Walk Graph Segmentation图分割算法

    1. 从细菌的趋化性谈起 0x1:物质化学浓度梯度 类似于概率分布中概率密度的概念.在溶液中存在不同的浓度区域. 如放一颗糖在水盆里,糖慢慢溶于水,糖附近的水含糖量比远离糖的水含糖量要高,也就是糖附近 ...

  8. [Machine Learning & Algorithm] 随机森林(Random Forest)

    1 什么是随机森林? 作为新兴起的.高度灵活的一种机器学习算法,随机森林(Random Forest,简称RF)拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来 ...

  9. 醉汉随机行走/随机漫步问题(Random Walk Randomized Algorithm Python)

    世界上有些问题看似是随机的(stochastic),没有规律可循,但很可能是人类还未发现和掌握这类事件的规律,所以说它们是随机发生的. 随机漫步(Random  Walk)是一种解决随机问题的方法,它 ...

随机推荐

  1. Android开发——网易云音乐使用的开源组件集合

    前言 网易云音乐Android版从第一版使用到现在,全新的 Material Design 界面,更加清新.简洁.同样也是音乐播放器开发者,我们确实需要思考,相同的功能,会如何选择.感谢开源,让我们有 ...

  2. Codeforces 678F Lena and Queries

    题意: 你有一个点集,有三种操作: 往集合里插入一个点\((x, y)\) 从集合中删除第\(i\)次操作插入的点 对于给出的\(q\),询问点集中\(x \cdot q + y\)的最大值 分析: ...

  3. Android 本地css引用

    /** 全局web样式 * 以前看不懂,现在仔细,耐心的看看,全懂了,认真的看一遍都懂了 * * * */ // 链接样式文件,代码块高亮的处理 public final static String ...

  4. Neural Network

    逻辑回归用神经网络节点的方式表示 前面已经介绍过逻辑回归的模型,样本为(x,y) 其中y的值为1或0,假设x有2个特征,则对应关系如下图所示.  实际情况是需要求需要三个参数,因此输入层需要添加一个 ...

  5. js武器库

    打造自己的 JavaScript 武器库 2017-12-14 SlaneYang JavaScript 自己打造一把趁手的武器,高效率完成前端业务代码. 前言 作为战斗在业务一线的前端,要想少加班, ...

  6. LINQ体验(9)——LINQ to SQL语句之Insert/Update/Delete操作

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Insert/Update/Delete操作.这个在我们的程序中最为常用了.我们直接看例子. Insert/Update/Delete操作 插入( ...

  7. BugKu-妹子的陌陌

    打开后看这张图片,先放winhex里面,文件头FFD8,是jpg图片.看文件尾并不是FFD9,所以binwalk分析一下. 发现有一个rar文件,然后用foremost分离.发现里面有个加密的rar文 ...

  8. python - 接口自动化测试 - HttpRequest - 接口测试类封装

    # -*- coding:utf-8 -*- ''' @project: ApiAutoTest @author: Jimmy @file: http_request.py @ide: PyCharm ...

  9. git基础之常用操作

    一.版本提交: (1)git add 文件名 (2)git commit -m "版本提交信息" 注:git分两个区:工作区+版本库 在电脑中看到的文件夹就是工作区 有一个隐藏的. ...

  10. Android数据储存之File

    openFileOutStream 和 openFileInStream FileInputStream fileInputStream = openFileInput(name);  打开应用下文件 ...