博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Algorithm | Random
阅读量:6001 次
发布时间:2019-06-20

本文共 1719 字,大约阅读时间需要 5 分钟。

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

1 class Random { 2 public: 3     Random(int n, int m):n(n), m(m) {} 4     void generate() { 5         srand(time(NULL));     6         for (int i = 0; i < n; ++i) data.push_back(i); 7         for (int i = 0; i < m; ++i) swap(data[i], data[i + rand() % (n - i)]); 8     } 9 10     void increase() {11         data.push_back(n++);12         int i = rand() % n;13         swap(data[i], data[n - 1]);14     }15 16     void print() const {17         for (int i = 0; i < m; ++i) 18             cout << data[i] << " ";19         cout << endl;20     }21 private:22     int n;23     int m;24     vector
data;25 };

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.

看完上面的解释。

重写了一遍。

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

 

转载于:https://www.cnblogs.com/linyx/p/3770466.html

你可能感兴趣的文章
docker之docker-machine用法
查看>>
IIS 7启用static JSON文件能POST方法
查看>>
P5205 【模板】多项式开根
查看>>
微博mini for Windows Phone 8 开发那些事
查看>>
redis文章索引
查看>>
OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE-2016-6210)
查看>>
Javascript回调函数
查看>>
可能是最简单的面向对象入门教程(二)为什么要有类型
查看>>
配置Openfiler做ISCS实验
查看>>
Maven启用代理访问
查看>>
LDAP & Implementation
查看>>
hdu 4597 Play Game
查看>>
hdu 1398 Square Coins (母函数)
查看>>
试验性的Numpy教程(译)
查看>>
twitter storm 源码走读之5 -- worker进程内部消息传递处理和数据结构分析
查看>>
CCF 201503-4 网络延时
查看>>
.net获取select控件中的文本内容
查看>>
Windows 8 Metro App开发[5]导航栏(AppBar)的使用
查看>>
shell expect
查看>>
Effective Java -- 使可变性最小化
查看>>