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的更多相关文章

  1. 茅坑杀手与Alias Method离散采样

    说起Alias,你可能第一个联想到的是Linux中的Alias命令,就像中世纪那些躲在茅坑下面(是真的,起码日本有粪坑忍者,没有马桶的年代就是社会的噩梦)进行刺杀的杀手一样,让人防不胜防,对于那些被这 ...

  2. Alias Method解决随机类型概率问题

    举个例子,游戏中玩家推倒了一个boss,会按如下概率掉落物品:10%掉武器 20%掉饰品 30%掉戒指 40%掉披风.现在要给出下一个掉落的物品类型,或者说一个掉落的随机序列,要求符合上述概率. 一般 ...

  3. java加密类型和算法名称

    项目里有各种加密方法,但从来没有仔细研究过.一般只是copy.这几天遇到一些问题,看了一下加密代码,觉得有些疑惑. 我们知道jdk已经为我们包装好了很多的算法.但究竟包装了哪些算法,怎么去掉这些算法我 ...

  4. Alias Method for Sampling 采样方法

    [Alias Method for Sampling]原理 对于处理离散分布的随机变量的取样问题,Alias Method for Sampling 是一种很高效的方式. 在初始好之后,每次取样的复杂 ...

  5. 封装算法: 模板方法(Template Method)模式

    template method(模板方法)模式是一种行为型设计模式.它在一个方法中定义了算法的骨架(这种方法被称为template method.模板方法),并将算法的详细步骤放到子类中去实现.tem ...

  6. paper 142:SDM算法--Supervised Descent Method

    对于face recognition的研究,我是认真的(认真expression,哈哈哈~~~~~~)许久没有写blog了,欢迎一起讨论. SDM(Supvised Descent Method)方法 ...

  7. 三维网格补洞算法(Poisson Method)

    下面介绍一种基于Poisson方程的三角网格补洞方法.该算法首先需要根据孔洞边界生成一个初始化补洞网格,然后通过法向估算和Poisson方程来修正补洞网格中三角面片的几何形状,使其能够适应并与周围的原 ...

  8. 三维网格补洞算法(Poisson Method)(转载)

    转载:https://www.cnblogs.com/shushen/p/5864042.html 下面介绍一种基于Poisson方程的三角网格补洞方法.该算法首先需要根据孔洞边界生成一个初始化补洞网 ...

  9. c#中奖算法的实现

    算法名称 Alias Method public class AliasMethod { /* The probability and alias tables. */ private int[] _ ...

随机推荐

  1. iframe页面script交互

    主页面: <html> <tr> <td> <div id=RightViewDiv> <iframe name=SubSeekFrame sty ...

  2. docker管理监控方案

    docker相关管理可分为四类:docker基础功能.docker监控.docker集群管理和docker系统认证管理.docker管理的基础或信息来源都是docker命令行或docker API. ...

  3. Linux设备管理——sysfs、udev

    What is the use of Sysfs sysfs is a pseudo file system provided by the Linux kernel that exports inf ...

  4. MSF MS12-020RDP漏洞攻击

    Metasploit利用远程桌面协议RDP拒绝访问漏洞(MS12-020) 漏洞描述:BUGTRAQ ID: 52354 CVE ID: CVE-2012-0152 远程桌面协议(RDP, Remot ...

  5. 安装lamp服务器

    1.安装http: $ yum install httpd 2.启动http: $ systemctl start httpd 3.访问:http://192.168.1.100 4.Installi ...

  6. python3使用WSGI启动服务

    WSGI是Web Server Gateway Interface的简称.它不是服务器,python模块,框架,API和任何种类的软件.它仅仅是一个服务器和应用间的接口规范. from wsgiref ...

  7. 使用flask搭建微信公众号:实现签到功能

    终于到了实战阶段.用微信公众号实现一个简单的签到功能. 前情提要: 微信公众号token验证失败 使用flask搭建微信公众号:完成token的验证 使用flask搭建微信公众号:接收与回复消息 程序 ...

  8. Apache虚拟主机&伪静态配置

    Apache基本操作 安装:yum install httpd 启动:systemctl start httpd 查看进程:ps -ef | grep httpd 查看端口:sudo netstat ...

  9. c#3.0 Lambda 表达式

    使用c# 2.0 中的匿名方法查找“内部包含abc子串的所有字符串”: list.FindAll( delegate(string s) { renturn s.indexof("abc&q ...

  10. Vue --- 基础指令

    目录 表单指令 条件指令 循环指令 分隔符(了解) 过滤器 计算属性 监听属性 冒泡排序 表单指令 使用方法: v-model 数据双向绑定 v-model绑定的变量可以影响表单标签的值,反过来表单标 ...