给定一个概率列表:[0.05, 0.15, 0.2, 0.6],要求生成的随机数符合该列表的概率分布。
---------------------------------------------------------------------------------------------------------------------------------------
在C/C++中,产生一个随机数,可以用下列方法:
点击(此处)折叠或打开
-
#include
> -
#include
> -
#include
> -
#include
> - using namespace std;
- int main(void)
- {
-
srand((unsigned)time(NULL)); // 用来设置rand()产生随机数时的随机数种子,参数必须是整数,如果每次参数都是一致的,rand()产生的随机数每次都是会一样
-
for(int i=0; i < 1000; i++)
-
{
-
count << rand() << '\t'; // 产生0至RAND_MAX间的随机数,RAND_MAX 大小视数据类型而定。
-
}
-
count << endl;
-
-
return 0;
- }
- ////////////////////////////////////////////////
- // 产生一定范围随机数的通用表示公式:
- // 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
- // 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
- // 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
- // 要取得(a,b)的随机整数,使用(rand() % (b-a-1))+ a + 1;
- // 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
- // 要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
-
// 要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。
其内部是使用线性同余法做的,因其周期长,在一定范围内,可以视为随机的。
我们可以产生0~1的随机数,将0~1分成是个数(0.1,0.2,0.3,...,1),每个数的出现的概率是相等的。
将0~1看做一个轮盘,将轮盘按给定的比例划分区域,0.05表示红色,0.15表示蓝色,0.2表示黄色,0.6表示绿色。轮盘中,红色的面积只有轮盘总面积的5%,蓝色的占15%,黄色占20%,绿色占60%。
设置一个指针指向轮盘,转动轮盘,指针最终停留在哪一块颜色的概率,一定是符合给定的概率分布的。
实现代码如下:
点击(此处)折叠或打开
- # -*- encoding: utf-8 -*-
- import sys, os
- import time
- import random
-
- def solution_one():
-
-
property = [0.05, 0.15, 0.2, 0.6]
-
selections = {red:0, blue:0, yellow:0, green:0}
- standard = 1.0 # 一个基准
- for i in range(10000):
-
NotAccept = True
-
while(NotAccept):
-
selectIndex = int(random.random() * len(property)) # 随机选择一个颜色
-
if(random.random() <= (property[selectIndex] / standard)): # 根据颜色所占比例随机选择
-
NotAccept = False # 选中
-
- selections[selectIndex] += 1
-
-
for color,count in selections.item():
-
print('color %s count : %d' % (color, count))
-
-
- def solution_two():
-
-
property = [0.05, 0.15, 0.2, 0.6]
-
selections = {red:0, blue:0, yellow:0, green:0}
-
sum_property = 0
-
rand = random.random()
-
- for i in property:
- sum_property += i
-
for rount in 1000: # 1000轮迭代测试
-
rand = random.random() * sum_property # 获取随机数
-
for index in selections:
-
rand -= property[index] # 判断一轮迭代中,四个颜色(在此题中)中被选中的是哪几个颜色
-
if(rand <= 0):
-
selections[index] += 1 # 选中的颜色加1
-
- for color,count in selections.item():
- print('color %s count : %d' % (color, count))
-
- def solution_three():
- property = [0.05, 0.15, 0.2, 0.6]
- selections = {red:0, blue:0, yellow:0, green:0}
- sum_property = 0
-
factor = 0
- rand = random.random()
- for i in property:
- sum_prtoperty += i
-
- for rount in 1000: # 迭代次数
- rand = random.random() * sum_property # 获取随机数
- for index in selections:
- factor += property[index] # 判断一轮迭代中,四个颜色(在此题中)中被选中的是哪几个颜色
- if(rand <= factor):
- selections[index] += 1 # 选中的颜色加1
-
- for color,count in selections.item():
-
print('color %s count : %d' % (color, count))
-
扩展:
该问题可以归纳为通过均匀分布随机数,生成指定概率分布的随机数问题。类似的问题还有:
1、通过均匀分布随机数生成符合正太分布的随机数;
2、通过正太分布随机数生成符合均匀分布的随机数;
3、生成指定分布的随机数
4、...........
参考:
1、Fitness proportionate selection
2、关于按概率生成随机数的问题的算法
3、根据相应概率产生随机数
4、生成特定分布随机数的方法(扩展阅读)
5、继续随机数:接受/拒绝方法(标准正态分布)(扩展阅读)
6、概率算法-均匀分布产生正态分布(扩展阅读)
7、花式生成正态分布(扩展阅读)(推荐)
8、C++ 生成随机数-GitHub(扩展阅读)