算法名称 Alias Method
public class AliasMethod {
/* The probability and alias tables. */
private int[] _alias;
private double[] _probability;
public AliasMethod(List<Double> probabilities) {
/* Allocate space for the probability and alias tables. */
_probability = new double[probabilities.Count];
_alias = new int[probabilities.Count];
/* Compute the average probability and cache it for later use. */
double average = 1.0 / probabilities.Count;
/* Create two stacks to act as worklists as we populate the tables. */
var small = new Stack<int>();
var large = new Stack<int>();
/* Populate the stacks with the input probabilities. */
for (int i = ; i < probabilities.Count; ++i) {
/* If the probability is below the average probability, then we add
* it to the small list; otherwise we add it to the large list.
*/
if (probabilities[i] >= average)
large.Push(i);
else
small.Push(i);
}
/* As a note: in the mathematical specification of the algorithm, we
* will always exhaust the small list before the big list. However,
* due to floating point inaccuracies, this is not necessarily true.
* Consequently, this inner loop (which tries to pair small and large
* elements) will have to check that both lists aren't empty.
*/
while (small.Count > && large.Count > ) {
/* Get the index of the small and the large probabilities. */
int less = small.Pop();
int more = large.Pop();
/* These probabilities have not yet been scaled up to be such that
* 1/n is given weight 1.0. We do this here instead.
*/
_probability[less] = probabilities[less] * probabilities.Count;
_alias[less] = more;
/* Decrease the probability of the larger one by the appropriate
* amount.
*/
probabilities[more] = (probabilities[more] + probabilities[less] - average);
/* If the new probability is less than the average, add it into the
* small list; otherwise add it to the large list.
*/
if (probabilities[more] >= average)
large.Push(more);
else
small.Push(more);
}
/* At this point, everything is in one list, which means that the
* remaining probabilities should all be 1/n. Based on this, set them
* appropriately. Due to numerical issues, we can't be sure which
* stack will hold the entries, so we empty both.
*/
while (small.Count > )
_probability[small.Pop()] = 1.0;
while (large.Count > )
_probability[large.Pop()] = 1.0;
}
/**
* Samples a value from the underlying distribution.
*
* @return A random value sampled from the underlying distribution.
*/
public int next() {
long tick = DateTime.Now.Ticks;
var seed = ((int)(tick & 0xffffffffL) | (int)(tick >> ));
unchecked {
seed = (seed + Guid.NewGuid().GetHashCode() + new Random().Next(, ));
}
var random = new Random(seed);
int column = random.Next(_probability.Length);
/* Generate a biased coin toss to determine which option to pick. */
bool coinToss = random.NextDouble() < _probability[column];
return coinToss ? column : _alias[column];
}
}
Dictionary<String, Double> map = new Dictionary<String, Double>();
map.Add("1金币", 0.2);
map.Add("2金币", 0.15);
map.Add("3金币", 0.1);
map.Add("4金币", 0.05);
map.Add("未中奖", 0.5); List<Double> list = new List<Double>(map.Values);
List<String> gifts = new List<String>(map.Keys); AliasMethod method = new AliasMethod(list); Dictionary<String, int> resultMap = new Dictionary<String, int>(); for (int i = ; i < ; i++) {
int index = method.next();
string key = gifts[index];
Console.WriteLine(index+":"+key);
}
源文:https://www.cnblogs.com/ahjesus/p/6038015.html
算法名称 Alias Method的更多相关文章
- 茅坑杀手与Alias Method离散采样
说起Alias,你可能第一个联想到的是Linux中的Alias命令,就像中世纪那些躲在茅坑下面(是真的,起码日本有粪坑忍者,没有马桶的年代就是社会的噩梦)进行刺杀的杀手一样,让人防不胜防,对于那些被这 ...
- Alias Method解决随机类型概率问题
举个例子,游戏中玩家推倒了一个boss,会按如下概率掉落物品:10%掉武器 20%掉饰品 30%掉戒指 40%掉披风.现在要给出下一个掉落的物品类型,或者说一个掉落的随机序列,要求符合上述概率. 一般 ...
- java加密类型和算法名称
项目里有各种加密方法,但从来没有仔细研究过.一般只是copy.这几天遇到一些问题,看了一下加密代码,觉得有些疑惑. 我们知道jdk已经为我们包装好了很多的算法.但究竟包装了哪些算法,怎么去掉这些算法我 ...
- Alias Method for Sampling 采样方法
[Alias Method for Sampling]原理 对于处理离散分布的随机变量的取样问题,Alias Method for Sampling 是一种很高效的方式. 在初始好之后,每次取样的复杂 ...
- 封装算法: 模板方法(Template Method)模式
template method(模板方法)模式是一种行为型设计模式.它在一个方法中定义了算法的骨架(这种方法被称为template method.模板方法),并将算法的详细步骤放到子类中去实现.tem ...
- paper 142:SDM算法--Supervised Descent Method
对于face recognition的研究,我是认真的(认真expression,哈哈哈~~~~~~)许久没有写blog了,欢迎一起讨论. SDM(Supvised Descent Method)方法 ...
- 三维网格补洞算法(Poisson Method)
下面介绍一种基于Poisson方程的三角网格补洞方法.该算法首先需要根据孔洞边界生成一个初始化补洞网格,然后通过法向估算和Poisson方程来修正补洞网格中三角面片的几何形状,使其能够适应并与周围的原 ...
- 三维网格补洞算法(Poisson Method)(转载)
转载:https://www.cnblogs.com/shushen/p/5864042.html 下面介绍一种基于Poisson方程的三角网格补洞方法.该算法首先需要根据孔洞边界生成一个初始化补洞网 ...
- c#中奖算法的实现
算法名称 Alias Method public class AliasMethod { /* The probability and alias tables. */ private int[] _ ...
随机推荐
- vue v-for中的item改变无法引起视图的更新
写过angularjs的同学知道,如果ng-repeat中的item绑定到对应的model,item改变是会引起视图的更新的,但是vue中不起作用,具体的解决办法: 在vue脚手架中,首先引入vue ...
- python之路第一天
2018-07-11星期三 创建自己的博客(博客园): 登陆 我的博客 随笔:所有人在博客中都能看见的文章 文章:别人看不见,只能URL访问--我把网页地址发给你,你才能看到 日志:别人看不到,URL ...
- 【HCIA Gauss】学习汇总-数据库管理(事务 权限 审计 OBDC JDBC)-6
事务控制事务提交 commit事务回滚 rollback savepoint 用于事务设置保存点 ----> savepoint s1 / savepoint s2 rollback to sa ...
- pip的安装、以及使用方法。
pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法. 1.pip下载安装 1.1 pip下载 1 # wget "https://py ...
- 利用mysql的inet_aton()和inet_ntoa()函数存储IP地址的方法
原文:https://www.jb51.net/article/29962.htm 当前很多应用都适用字符串char(15)来存储IP地址(占用16个字节),利用inet_aton()和inet_nt ...
- 个人第5次作业-Alpha2项目的测试
这个作业属于哪个课程 系统分析与设计 这个作业要求在哪里 作业要求 团队名称 卓越Code 这个作业的目标 选取3个非自己所在团队进行项目测试,协助该团队进行项目改进 前言 魏家田 201731062 ...
- springboot整合mybatis及封装curd操作-配置文件
1 配置文件 application.properties #server server.port=8090 server.address=127.0.0.1 server.session.tim ...
- js插件---webuploader 使用(lavarel中使用)
js插件---webuploader 使用(lavarel中使用) 一.总结 一句话总结: 多去看几个具体使用的实例,很多blog教程都有坑,多看几个交叉印证可以没那么多坑 1.webuploader ...
- Git学习笔记--配置(二)
由之前文章,总结得出Git的特点: 最优的存储能力: 非凡性能: 开源的: 管理成本低: 很容易做备份: 支持离线操作: 很容易定制工作流程: Git is a free and open sourc ...
- select 与 I/O多路转接
参考博客:http://blog.sina.com.cn/s/blog_607072980102uxcw.html I/0多路转接: 描述符表示某个I/O.构造一张有关描述符的数据表,调用select ...