Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 离散概率分布算法的采样_Algorithm - Fatal编程技术网

Algorithm 离散概率分布算法的采样

Algorithm 离散概率分布算法的采样,algorithm,Algorithm,我正在解决Sedgewick书中的一个任务: 使用构造函数编写一个类示例,该构造函数接受数组p[]的 双值作为参数,支持以下两种操作: random()-返回概率为p[i]/T的索引i(其中T是 p[]中的数字总和) 我认为有一个简单的解决方案:将所有边界值存储在数组中,并找到第一个低于随机样本的值,例如,我们有(值,权重)对:(1,10.0),(2,20.0),(3,10.0),(4,10.0)。我们把它转换成 (1,0.0),(2,10.0),(3,30.0),(4,40),对随机值[0-5

我正在解决Sedgewick书中的一个任务:

使用构造函数编写一个类示例,该构造函数接受数组p[]的 双值作为参数,支持以下两种操作: random()-返回概率为p[i]/T的索引i(其中T是 p[]中的数字总和)

我认为有一个简单的解决方案:将所有边界值存储在数组中,并找到第一个低于随机样本的值,例如,我们有(值,权重)对:(1,10.0),(2,20.0),(3,10.0),(4,10.0)。我们把它转换成 (1,0.0),(2,10.0),(3,30.0),(4,40),对随机值[0-50](例如,35)进行采样,发现它大于30,所以答案是“3”

但书中有一个建议:

使用一个完整的二叉树,其中每个节点都有隐含的权重p[i]。 在每个节点中存储其内部所有节点的累积权重 子树。若要生成随机索引,请选择介于0和0之间的随机数 和T,并使用累积权重确定 要探索的子树

我在github上看到了这个解决方案:


但我不明白它为什么会起作用:我们不需要表示范围,而是用一些树来表示节点,比如(3,10),(4,10),搜索距离随机样本最近的节点如何帮助找到正确的节点?

你的想法是对的,但不是很正确。你想做什么。您所考虑的逐步函数是给定离散分布的逆累积密度函数(cdf)。更传统的做法是将搜索值写在间隔[0..1]的X轴上。对于1、2、3和4,权重分别为1/5、2/5、1/5和1/5。您希望将间隔拆分为如此大小的片段,并将这些间隔映射到各自的值:

[0   .. 1/5) ->  1   // Note interval widths are 1/5,2/5,1/5,1/5 as desired.
[1/5 .. 3/5) ->  2
[3/5 .. 4/5) ->  3
[4/5 ..   1) ->  4
正如您所说,将区间的顶部及其值存储在一个数组中就足够了

struct IntervalTop {
  double r;
  int value;
} cdf[] = {{.2, 1}, {.6, 2}, {.8, 3}, {1.0, 4}};
现在在[0..1]中生成一个随机值,并查找相应的子区间以确定该值。例如,0.1在第一个区间中,因此返回1.0.7在第三个区间中,因此返回3。简单的线性搜索对初学者来说是可行的:

double r = ... // Compute random double 0.0 <= r < 1.0 .
for (int i = 0; ; ++i)
  if (cdf[i].r > r) 
     return cdf[i].value;
实际上,算法不需要权重(这就是为什么s说它们是“隐式的”),但在这里包含权重可以更容易地看到发生了什么

如上所述,您将在[0..1]中生成一个随机数r,但在这里您将使用r的值作为指导搜索树

您可以通过查看tree.t、tree.left.t和tree.right.t(缺少的子项相当于.t值为零)并使用这些值来做出与上面的二进制搜索相同的决定

我就到此为止,这样你的乐趣就不会被破坏了

                  ____3(w=1/5,t=1)____
                 /                     \
        2(w=2/5,t=3/5)           4 (w=1/5,t=1/5)
        /
1(w=1/5,t=1/5)