Line论文中的Alias Sampling Algorithm 分析
来源:互联网 发布:java自带的观察者模式 编辑:程序博客网 时间:2024/05/20 06:06
http://blog.csdn.net/haolexiao/article/details/65157026
找了一下这篇写的最清晰了,然后结合Line的源码分析一下。
原理:
原文举例如下:比如一个随机事件包含四种情况,每种情况发生的概率分别为: 1/2,1/3,1/12,1/12,问怎么用产生符合这个概率的采样方法。
Alias方法按照均值1/N进行归一化,其总面积为N,并且分为1*N个长方形,每一列面积为1。
通过将概率大于1的事件的面积补到概率小于1的事件中,来保证每列的概率和为1,并且每一列最多两个事件。
具体带图的看原博客。
Alias Method具体算法如下:
1. 将整个概率分布拉平成为一个1*N的长方形即为Alias Table,构建上面那张图之后,储存两个数组:
(1)一个里面存着第i列对应的事件i矩形站的面积百分比【也即其概率】,上图的话数组就为Prab[2/3, 1, 1/3, 1/3],
(2)另一个数组里面储存着第i列不是事件i的另外一个事件的标号,像上图就是Alias[2 NULL 1 1]
2.产生两个随机数,第一个产生1~N 之间的整数i,决定落在哪一列。扔第二次骰子,0~1之间的任意数,判断其与Prab[i]大小,如果小于Prab[i],则采样i,如果大于Prab[i],则采样Alias[i]
在代码中的实现思路:
构建方法:
1.找出其中面积小于等于1的列,如i列,这些列说明其一定要被别的事件矩形填上,所以在Prab[i]中填上其面积
2.然后从面积大于1的列中,选出一个,比如j列,用它将第i列填满,然后Alias[i] = j,第j列面积减去填充用掉的面积。
以上两个步骤一直循环,直到所有列的面积都为1了为止。
然后结合下line论文中采用这个方法的源码分析一下,加了注释供理解参考。
/* The alias sampling algorithm, which is used to sample an edge in O(1) time. */void InitAliasTable(){ alias = (long long *)malloc(num_edges*sizeof(long long)); prob = (double *)malloc(num_edges*sizeof(double));//概率数组 存第i列事件i占的面积百分比 //如果初始化失败 if (alias == NULL || prob == NULL) { printf("Error: memory allocation failed!\n"); exit(1); } double *norm_prob = (double*)malloc(num_edges*sizeof(double)); //归一化的概率数组 存放 i列事件i占的面积百分比 long long *large_block = (long long*)malloc(num_edges*sizeof(long long));//面积大于1的数组 long long *small_block = (long long*)malloc(num_edges*sizeof(long long));//面积小于1的数组 //如果初始化失败 if (norm_prob == NULL || large_block == NULL || small_block == NULL) { printf("Error: memory allocation failed!\n"); exit(1); } double sum = 0; long long cur_small_block, cur_large_block; long long num_small_block = 0, num_large_block = 0; for (long long k = 0; k != num_edges; k++) sum += edge_weight[k];//统计所有边的权重和 for (long long k = 0; k != num_edges; k++) norm_prob[k] = edge_weight[k] * num_edges / sum;//得到第i列中事件i本身所占的百分比 每一列面积为1 总面积为1*num_edges //分为两组,占比大于1和小于1的 for (long long k = num_edges - 1; k >= 0; k--) { if (norm_prob[k]<1) small_block[num_small_block++] = k;//占比小于1 else large_block[num_large_block++] = k;//占比大于1 } while (num_small_block && num_large_block)//直到每一列的占比都为1 { cur_small_block = small_block[--num_small_block];//当前小边的序号 cur_large_block = large_block[--num_large_block];//当前大边的序号 prob[cur_small_block] = norm_prob[cur_small_block];//把归一化占比赋给Prob alias[cur_small_block] = cur_large_block;//用面积大于1的去填充面积小于1的 alias中存,不是事件i的序号,即用来填充的事件的序号 norm_prob[cur_large_block] = norm_prob[cur_large_block] + norm_prob[cur_small_block] - 1;//得到减去用来填充的剩下的面积 if (norm_prob[cur_large_block] < 1)//如果剩下的面积小于1 则归到小块面积 small_block[num_small_block++] = cur_large_block; else large_block[num_large_block++] = cur_large_block; } while (num_large_block) prob[large_block[--num_large_block]] = 1; while (num_small_block) prob[small_block[--num_small_block]] = 1; free(norm_prob); free(small_block); free(large_block);}
- Line论文中的Alias Sampling Algorithm 分析
- Alias Sampling Algorithm With GSL C代码实现
- Alias Method for Sampling
- Alias Method for Sampling
- Sampling Importance Re-sampling Algorithm
- Alias sampling 算法用Python实现
- 【论文】New baseline correction algorithm for text-line recognition with bidirectional recurrent neural
- 蓄水池抽样算法 (Reservoir Sampling Algorithm)
- 蓄水池抽样算法 (Reservoir Sampling Algorithm)
- Bresenham line algorithm
- sweeping line algorithm -- calculate line segment intersections
- scan line polygon fill algorithm
- 蓄水池抽样(Reservoir Sampling)分析
- Markov Chain Monte Carlo Algorithm and Gibbs Sampling
- update中的alias
- Sampling
- 关于sampling softmax 中重要性采样的论文阅读笔记
- Line clipping之cohen-sutherland Algorithm
- Swift基础 错误处理
- Git的17条基本用法
- Dubbo/Dubbox的服务消费(一)- 服务代理的创建
- Faster-RCNN使用时Error parsing text-format caffe.NetParameter
- hello.ko---Makefile
- Line论文中的Alias Sampling Algorithm 分析
- 回首Java——堆排序
- 会场安排问题
- UE4实现纹理缩放(将纹理坐标进行缩放)
- 自己动手实现一个Android断点下载
- 数据库一表分两表导入数据的SQL 语句
- appDelegate
- Centos7安装-单节点Torque
- 管道物流装卸系统